【发布时间】:2021-10-29 09:44:59
【问题描述】:
我正在使用 express.js、react.js 和 socket.io 构建一个具有聊天功能的应用程序。 Here is a minimal version with the bug reproduced on Github.
问题是服务器的socket.on() 总是触发两次,这对我来说没有什么明显的原因。
据我所知,客户端只发送一个.emit,但服务器的.on 总是触发两次(我相当确定事件处理程序不会绑定两次),无论有多少客户端已连接,或者实际上我是如何重构代码的。
发送客户端的表单(输入 + 按钮)将消息附加到其本地消息列表中,然后将 MESSAGE_NEW 发送到减速器。
首先是Socket.js 文件。
import React from 'react'
import socketio from 'socket.io-client'
export const socket = socketio.connect('ws://localhost:3001')
export const SocketContext = React.createContext()
这是来自Chat.js 的提交处理程序代码(这似乎工作正常,只调度一次):
const handleSubmit = e => {
e.preventDefault()
if (message === '') return
setMessages(messages => [...messages, message])
dispatch({ type: 'MESSAGE_NEW', payload: message })
setMessage('')
}
这是/Reducer.js,.emit 是信号(似乎也可以正常工作,只触发一次)。
import { useContext } from 'react'
import { SocketContext } from './Socket'
export default function Reducer(state, action) {
const socket = useContext(SocketContext)
switch (action.type) {
case 'MESSAGE_NEW':
// this only fires once, as it should
console.log('emitting socket')
socket.emit('message:new', action.payload)
break
default:
return state
}
}
但这里是来自/server/index.js 的相关部分,这就是问题所在。无论我尝试过什么,.on 总是会触发两次。
io.on('connection', socket => {
console.log('New client connected:', socket.id)
socket.on('message:new', message => {
// this always fires twice, i do not understand why
console.log('message:new: ', message, socket.id)
socket.broadcast.emit('message:new', message)
})
})
更新: 我发现将socket.emit 从Reducer.js 移动到Chat.js 中的handleSubmit 可以正常工作。我不明白为什么,因为 Reducer 不会触发两次。
【问题讨论】: