React和Socket.io:能够获取初始数据 - 但是当新帖子进入时视图不会更新

fre*_*447 8 sockets node.js socket.io reactjs

不确定问题是我如何设置套接字 - 或者我是否错误地尝试使用React渲染数据.

我可以使用我的套接字成功引入数据 - 但是当新数据发布到服务器时它不会处于更新状态.我的目的是让React中的状态自动呈现新数据,由于套接字连接,它始终处于活动状态.

这是我的客户端应用程序从服务器获取消息并呈现它们:

var Chat = React.createClass({
  getInitialState: function() {
    return {
      messages: null
    }
  },
  componentWillMount: function(){
    var self = this;
    socket.emit('getMessages');
    socket.on('serverMessages', function (data) {
      self.setState({messages: data})
    });
  },
  render: function() {
    var messages = this.state.messages ? <MessageList messages={this.state.messages}/> : null
    return (
      <div className="jumbotron">
        { messages }
        <MessageForm submitMessage={this.submitMessage}/>
      </div>
      );
  }
});
Run Code Online (Sandbox Code Playgroud)

以防万一这是我的服务器代码发出数据:

io.on('connection', function (socket) {

  socket.on('getMessages', function (data) {
    Message.find(function(err, messages){
      socket.emit('serverMessages', messages);
    })
  });

});
Run Code Online (Sandbox Code Playgroud)

Mic*_*ker 6

就目前而言,一旦加载了组件,您就“只是”从服务器获取数据。为了获得更“实时”的东西,您需要使用emit您定期指定的相同语句ping 服务器(这违背了使用 websockets 的意义,实际上,您可以使用长轮询)或让服务器定期发送向所有客户提供新数据。

您可以执行以下任一操作:

A)客户端:“轮询”信息[不理想]

注意:我最初把它放在我的答案中,因为我看到 OP 在加载控制器时正在“轮询”。我没有点击,这可能是因为控制器可能没有加载 websocket,所以在连接上发送数据在这里可能不起作用。我的错。

替换socket.emit('getMessages')为可以定期“轮询” websocket 数据的东西:

setInterval(function () {
    socket.emit('getMessages')
}, 10000); /* Request data from the socket every 10 seconds */
Run Code Online (Sandbox Code Playgroud)

或者

B) 服务器端:在新数据可用时发送。[最好的办法]

通过客户端数组跟踪所有客户端,并在会话结束时将其从其中删除。

var clients = [];

io.on('connection', function (socket) {
    clients.push(socket);

    socket.on('end', function () {
        // Could also splice the array below, but it still works.
        delete clients[clients.indexOf(socket)];
    });


    /* Previous logic for server goes here */
});
Run Code Online (Sandbox Code Playgroud)

当您需要从数据库/数据存储推送新消息时运行此代码:

for (var i in clients) {
    clients[i].emit('serverMessages', /* messages object */);
}
Run Code Online (Sandbox Code Playgroud)


kwc*_*cto 4

您的服务器代码仅在初始套接字上触发connection

服务器:

socket.on('getMessages', function (data) {
  Message.find(function(err, messages){
    socket.emit('serverMessages', messages);
  })
});
Run Code Online (Sandbox Code Playgroud)

客户:

var Chat = React.createClass({
  getInitialState: function() {
    return {
      messages: null
    }
  },
  componentWillMount: function(){
    var self = this;
    socket.emit('getMessages');
    socket.on('serverMessages', function (data) {
      self.setState({messages: data})
    });
  },
  render: function() {
    var messages = this.state.messages ? <MessageList messages={this.state.messages}/> : null
    return (
      <div className="jumbotron">
        { messages }
      </div>
      );
  }
});
Run Code Online (Sandbox Code Playgroud)

根据命名约定,您似乎Message.find()正在提取一条消息。我建议澄清标签以匹配基数。