React Native、NodeJS、Socket.io

Posted

技术标签:

【中文标题】React Native、NodeJS、Socket.io【英文标题】:React Native, NodeJS, Socket.io 【发布时间】:2021-03-30 06:53:55 【问题描述】:

我正在尝试在我的应用程序中实现 1-1 私人消息传递功能,如果两个用户同时在聊天屏幕上,则两个用户可以实时交换消息,如果不是,则消息存储在我的 postgres 数据库中,并且当用户再次打开聊天时,它们会被加载。

目前使用我的代码,当两个用户聊天都打开时,当我尝试发送消息时,消息不会实时发送,我需要刷新应用程序才能更新聊天。我认为我的套接字正在工作,因为我的控制台日志在前端和后端控制台中都得到了返回。

我的问题是如何使消息生效并正确更新我的平面列表(即新消息出现在倒排列表的底部)?

这是我的代码:

客户端

  const message = route.params.message;
  const [messages, setMessages] = useState([]);
  const [text, setText] = useState('');
  const [socket, setSocket] = useState(null);
  const  user  = useAuth();

  useEffect(() => 
  const newsocket =io.connect(socketURL)
  setMessages(message.Messages)
  newsocket.on('connect', msg => 
  console.log(`user: $user.id has joined conversation $message.id`)
  setSocket(newsocket)
  );

  newsocket.on("send_message", (msg) => 
  console.log("this is the chat message:", msg);
  const data = [...messages]; 
  data.push(msg);
  setMessages(data); 
  );

  return(()=>newsocket.close());
  , []);

  const onSend = (ConversationId,senderId,receiverId,message) => 
messagesApi.sendMessage(ConversationId,senderId,receiverId,message);
setText("")
const to = (user.id===route.params.message.user1? 
route.params.message.user2:route.params.message.user1)
    socket.emit(
    'message',  to: to, from: user.id, message,ConversationId );
  ;

 const updateText=(text)=>
 setText(text);
 

<FlatList
    inverted
    data=messages
    keyExtractor=(item,index)=>index.toString()
    extraData=messages
    renderItem=(item,index)=>(
        <>
        <Text>
         moment(item.createdAt).fromNow()
         </Text>
        <MessageBubble
        text=item.message
        mine=item.senderId !== user.id
        />
         </>
    )   
    bounces=false  
    />
    <View style=styles.messageBoxContainer>
        <TextInput 
        onChangeText=updateText 
        value=text 
        />
        <TouchableOpacity 
         onPress=()=>
         onSend(
         message.id,
         user.id, 
         (user.id===message.user1?message.user2:message.user1),
         text
         )
         >
         <Text>Send</Text>
        </TouchableOpacity>
     </View>

服务器端

const express = require("express");
const app = express();
const http = require("http");
const socket = require("socket.io")
const server=http.createServer(app);
const io =socket(server)

io.on('connection', (socket) => 
console.log("connected")
socket.on('message', (data) => 
console.log(data)
socket.emit('send_message',  message: data.message, receiverId: 
data.to,senderId:data.from,conversationId:data.ConversationId )
);
);

提前谢谢你,我已经尝试解决这个问题好几个星期了,但无法解决。非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

由于 Srikanth 对此Creating a private chat between a key using a node.js and socket.io 的回答,经过多次尝试,我设法让它工作。

客户

useEffect(() => 
const newsocket =io.connect("http://192.168.1.103:9000")
setMessages(message.Messages)

newsocket.on('connect', msg => 
    console.log(`user: $user.id has joined conversation $message.id`)
    setSocket(newsocket)
    newsocket.emit('subscribe', message.id);
 );

newsocket.on("send_message", (msg) => 
    console.log("this is the chat messages:", msg);
    setMessages(messages => messages.concat(msg))
  );
 
 return(()=>newsocket.close());

 , []);

const onSend = (ConversationId,senderId,receiverId,message) => 
console.log("sent")
const to = (user.id===route.params.message.user1? 
route.params.message.user2:route.params.message.user1)
socket.emit('message',  to: to, from: user.id, message,ConversationId );
setText("")
messagesApi.sendMessage(ConversationId,senderId,receiverId,message);
;

服务器

io.on('connection',(socket)=>
console.log('User '+socket.id+' connected')

socket.on('subscribe', (room)=> 
console.log('joining room', room);
socket.join(room);
);

socket.on('message', (data) => 
console.log(data)
console.log('sending room post',data.ConversationId)
io.sockets.in(data.ConversationId).emit('send_message',  message: 
data.message, receiverId: 
data.to,senderId:data.from,conversationId:data.ConversationId );
)
)

我读过很多建议不要在 1-1 私人消息中使用房间,但这是唯一可行的方法。

【讨论】:

以上是关于React Native、NodeJS、Socket.io的主要内容,如果未能解决你的问题,请参考以下文章

[NodeJS] Basic knowledge about NodeJS due to React Native

react-native WebSocket & nodejs WebSocket

React Native、NodeJS、Socket.io

使用 OneSingnal 从 NodeJS 发送通知推送到 React Native

如何使用 NodeJS 和 SocketIO 在 React-Native 中处理离线消息

使用路径“lib/arm64-v8a/libnode.so”找到 2 个文件 - nodejs-mobile-react-native 的 jniLibs 问题