show
, вероятно, не лучший выбор для этого. Вместо этого я буду использовать pyplot.draw()
. Вы также можете включить небольшую задержку (например, time.sleep(0.05)
) в цикле, чтобы вы могли видеть сюжеты. Если я сделаю эти изменения в вашем примере, это сработает для меня, и я вижу, что каждый пункт появляется по одному.
Во-первых, когда сокет подключается к вашему серверу, добавьте этот сокет в комнату и немедленно отправьте свою историю чата.
io.on('connection', async (socket) => {
socket.user = socket.request.session.user;
socket.join('chat');
try {
const messages = await Message.find({});
socket.emit('history', messages);
} catch (err) {
// Handle this error properly.
console.error(err);
}
});
Затем, позже, когда вы получите сообщение, вы захотите сохранить это сообщение и отправить его во все сокеты вашей комнаты чата.
socket.on("sendMessage", (msg, callback) => {
const message = new Message({ message: msg, sender: socket.user });
message.save(function(err) {
if (err) {
return callback(err);
}
io.to('chat').emit('message', message);
});
});
Наконец, на стороне клиента вы захотите прослушать историческое событие. Получив его, вы захотите очистить текущую историю чата и заменить ее тем, что сообщает сервер. Возможно, это будет выглядеть примерно так
socket.on('history', (messages) => {
this.setState({ messages });
});
Вы также захотите прослушать это message
событие, но с этим событием вы только добавите сообщение в свою историю. Это может выглядеть примерно как
socket.on('message', (message) => {
this.setState({ messages: [ ...messages, message ] });
});
Слово предупреждения, если, когда вы сообщаете серверу о новом сообщении, не добавляйте его в свой массив состояний messages
, пока не получите событие message
. Если вы сделаете это, вы заметите двойные сообщения. Например, это может выглядеть примерно так:
onSendMessage(evnt) {
evnt.preventDefault();
socket.emit("sendMessage", msg);
this.setState({ msg: "" });
}
Примечание : Получив некоторую обратную связь от OP, я хотел добавить раздел о том, куда поместить обработчики событий, прикрепленные к сокету. (т.е. все socket.on
с). Мое предложение было бы добавить этот код в файл, который определяет схему Message
в нижней части файла в обратном вызове io.on('connection')
. Например,
const Message = new mongoose.Schema({/*...*/});
io.on('connection', (socket) => {
// Everything else I wrote above...
socket.on('sendMessage', (msg, callback) => {
// ...
});
});
На стороне клиента обработчики событий, вероятно, будут зарегистрированы, когда смонтирован компонент чата. Например,
class ChatComponent extends React.Component {
componentDidMount() {
this.socket = io('https://your-server-or-localhost/');
this.socket.on('history', (messages) => {
// See above...
});
}
}