2016-04-15 1 views
8

Не уверен, что проблема связана с настройкой моих сокетов - или если я неправильно пытаюсь отобразить данные с Реакцией.React и Socket.io: Возможность получения исходных данных - но просмотр не обновляется, когда новое сообщение приходит в

Я могу с легкостью извлекать данные с помощью своего сокета, но он не обновляется, когда новые данные отправляются на сервер. Мое намерение состоит в том, чтобы состояние в 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> 
    ); 
    } 
}); 

Только в случае вот мой сервер код, который выдает данные:

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

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

}); 

ответ

3

Ваш код сервера только стрельба по первому гнезду connection.

Сервер:

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

Клиент:

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> 
    ); 
    } 
}); 

на основе именования, также кажется, что ваш Message.find() тянет одно сообщение. Я бы рекомендовал уточнить маркировку для соответствия мощности.

+0

Код был поспешно написан в браузере и не проверен, поэтому приносим извинения, если есть опечатки/логические ошибки. Ключевым недостатком в исходном примере был отсутствующий обработчик событий для 'getMessages' – kwcto

+0

Спасибо @kwcto - я внедрил ваши отзывы, но он по-прежнему ведет себя одинаково. Новые сообщения появляются только при обновлении страницы. (Я обновил вопрос, чтобы отразить новую реализацию) – fresh5447

4

Попробуйте это:

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> 
    ); 
    } 
}); 
4

Как прямо сейчас, вы «просто» захват данных с сервера после загрузки компонента. Чтобы получить что-то более «реальное время», вы захотите либо ping-сервер с тем же оператором emit, который вы указали регулярно (что поражает точку использования веб-узлов, на самом деле, вы можете использовать длительный опрос) или регулярно на сервере отправлять новые данные всем клиентам.

Вы можете сделать ЯВНО:

A) на сторону клиента: «опрос» для получения информации [Не Ideal]

Примечание: Сначала я положил это в моем ответе, потому что я видел, что ОП было «опрос» при загрузке контроллера. Я не нажимал на это, возможно, потому, что контроллер не может быть загружен с помощью websocket, поэтому отправка данных на соединение может не работать здесь. Виноват.

Заменить socket.emit('getMessages') с чем-то, что будет "опрос" WebSocket регулярно для данных:

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

ИЛИ

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 */ 
}); 

Выполнить этот код, когда нужно нажать новые сообщения из хранилища базы данных/данных:

for (var i in clients) { 
    clients[i].emit('serverMessages', /* messages object */); 
} 
+0

Что касается опции A: просто не так, как нужно, чтобы опрос был на клиенте. Не подключен ли к сокету клиентский сокет для создания живого потока данных ? – fresh5447

+0

Вариант B - лучший способ - я думал, что упомянул об этом, но, очевидно, нет. Я выпустил вас, сначала был опрос, но таким образом это имеет смысл, если ваш компонент не загружен при подключении к веб-расписанию или так: P –

+0

Использование широковещательных/эмиттных и пространственных пространств или помещений может быть более безопасным (и проще), чем сохранение отслеживать клиентов (массив 'clients'). После запуска нескольких экземпляров узла этот массив 'clients' будет содержать только экземпляры, связанные с этим конкретным хостом. То же самое верно по умолчанию с socket.io, но он официально рекомендовал способы работы с несколькими хостами https://socket.io/docs/using-multiple-nodes/ – tybro0103

1

Возможен ли его благодаря методе componentWillMount жизненного цикла? Не могли бы вы попробовать componentDidMount.

Похоже, что рендер увидит обновление состояния, но будет выполнен только один раз, несмотря на изменение состояния в соответствии с facebook.

Смежные вопросы