socket.io更新组件的问题,以在聊天室中显示新消息

时间:2016-10-24 08:39:17

标签: javascript node.js sockets reactjs socket.io

我正在使用React,Node / Express和socket.io构建聊天应用。我通过http.createServer将套接字成功设置到我的快速服务器。我在客户端和服务器上有一个监听器,用于监听进入聊天室的新消息。理想情况下,我希望在有其他消息时更新聊天的每个实例,例如任何曾经存在的聊天室:)

现在我在客户端和服务器之间进行了成功的监听。我知道因为console.log服务器端。但是,当我从其他实例提交新邮件时,我不会重新呈现聊天组件。

所以我的客户端(同样是React)组件中的代码如下所示,我在index.html中使用带有脚本标记的套接字CDN(脚本标记未显示):

这里是套接字CDN

var socket = io('')

这就是你看到客户端的套接字:

componentDidMount() {
  return axios.get(`api/messages`)
    .then((result) => {
      if (result.data.length) {
        this.setState({ 
          messages: [ ...this.state.messages, ...result.data] 
        } , () => { 
          console.log("The state after messages are mounted : ", this.state) 
        })
      }
    })
    .catch((err) => { throw err})
      socket.on('new message', msg => {
      this.newMessage(msg);
    })
};

newMessage(msg) {
  this.setState({
    messages: [...this.state.messages, msg]
  }, () => {
    this.setState({ message: '' })
    return this.scrollToBottom()
  });
};


onSubmitMessage(event) {
  event.preventDefault();
  const content = this.state.message;

  const msg = {
    content,
    createdAt : new Date(),
    userId : "one",
    chatRoomId : "two"
  }
  axios.post(`api/messages/`, msg)
  .then(() => {
    this.newMessage(msg);
    socket.emit('new message', msg); //HERE'S THE SOCKETS IN ACTION
  })
};

这是服务器端代码Node / Express:

//in server.js
const io = new socketIo(server)
require('./socketEvents')(io);
const connections = [];

然后是我的套接字事件的单独文件     //在socketEvents.js

module.exports = (io) => {

  io.on('connection', (socket) => {
    console.log("Beautiful sockets are connected")

    socket.once('disconnect', () => {
      console.log("socket is disconnected");
    });

    //DOESN'T DO ANYTHING YET 
    socket.on('join global', (username) => {
      socket.join(username);
      console.log("New user in the global chat : ", username)
    });

    socket.on('new message', (msg) => {
      console.log("The new message from sockets : ", msg);
      socket.emit('new message', msg.content);
    });

  });
}

我的套接字服务器端与客户端链接。我只是没有在不同的实例中看到新消息。是因为我在服务器收到消息后没有重新渲染吗?

提前致谢,如果您需要我澄清一切,请告诉我。

干杯!

1 个答案:

答案 0 :(得分:0)

我想通了......我将通过演练离开这篇文章,试图帮助其他有插座问题的人。我可以发布关于它的博客。如果我这样做会更新。

因此,代码在客户端侦听要在onSubmitMessage函数内发送的消息。

onSubmitMessage(event) {
  event.preventDefault(); //prevents HTML <form> from going on its own post
  const content = this.state.message;

  //Create message object
  const msg = {
    content,
    createdAt : new Date(),
    userId : "one",
    chatRoomId : "two"
  }

  //HERE'S THE IMPORTANT PART!!!
  axios.post(`api/messages/`, msg)
  .then(() => {

    // wrapped in a promise, send a handler to server called 
    // ('new message') with the message object
    this.newMessage(msg);
    socket.emit('new message', msg);
  })
  .then(() => {
    //Another promise then waits for the handler to come back from server 

    //*****IMPORTANT*************
    //Then invoke newMessage function to get the post on all sockets
    socket.on('message', (msg) => {
      this.newMessage(msg);
    })
  })

};

现在在服务器端,这就是发生的事情:

// This is where the listener is for the client side handle
socket.on('new message', (msg) => {
  // broadcast.emit will send the msg object back to client side and
  // post to every instance expcept for the creator of the message
  socket.broadcast.emit('message', msg);
});

所以数据路径是(C)客户端,(S)服务器:

从用户接收消息对象和--------&gt;

(C)socket.emit(&#39; new message&#39;)-----&gt; (S)socket.on(&#39; new message&#39;)-------&gt; (S)socket.broadcast.emit(&#39; message&#39;)--------&gt; (C)socket.on(&#39; message&#39;)

回到客户端,我可以调用我的newMessage函数,它将消息设置为状态,以便我可以显示它。

我希望有人觉得这很有用!令人惊讶的是,这似乎在Stack上相对没有答案。如果有人有任何问题可以随意提问!