【问题标题】:SocketIO Disconnect Leaving Socket ListeningSocketIO Disconnect 离开 Socket 监听
【发布时间】:2015-04-25 05:34:18
【问题描述】:

我正在尝试将 SocketIO 与 Redis Pub/Sub 结合使用来监视我的应用程序中的事件。到目前为止,我为服务器提供了以下内容

io.on 'connection', (socket) ->
  log.info "Connection established. [Socket: #{socket.id}]"

  socket.on 'join_room', (roomName) ->
    log.info "Join room '#{roomName}'. [Socket: #{socket.id}]"
    socket.join roomName

  redis.on 'message', (redisChannel, message) ->
    message = JSON.parse message
    log.info "Room: #{message.room} - Event: #{message.event} - Message: #{message.message}"
    io.sockets.in(message.room).emit(message.event, message.message)

  socket.on 'disconnect', ->
    log.info "Connection destroyed. [Socket #{socket.id}]"

然后,在客户端,我有

  socket = io.connect('http://127.0.0.1:3333/')   
  socket.emit('join_room', 'login_events')
  socket.emit('join_room', 'cj_alerts')

  socket.on 'failed_login', (msg) ->
    console.log msg

  socket.on 'successful_login', (msg) ->
    console.log msg

当服务器运行时,我可以使用$redis.publish 'redisChannel', {:room => 'room', :event => 'failed_login', :message => 'message'}.to_jsonredis.on 'message' 位正确触发。事实上,一切都很好。

当我刷新客户端代码所在的页面而不重新启动服务器时,问题就出现了。我的“连接被破坏”日志正确出现,但似乎连接从未真正消失。每次刷新时,都会添加另一个侦听器。下面的屏幕截图应该有助于澄清我的意思。

每个“连接被破坏”/“连接已建立”都表示刷新。

我还假设客户端的代码将基于每个浏览器窗口。然而,即使我打开一个新的浏览器,我得到的输出显示所有的事件都被应用到每个窗口。

任何关于它为什么这样做以及正确方法的提示将不胜感激。

【问题讨论】:

  • 您的客户端代码是“每个浏览器窗口”,而不是“每个客户端”,因此每个浏览器窗口都有一个唯一的连接。您必须使用某种持久性用户标识符来为每个客户端创建任何内容,然后编写代码来强制每个客户端策略一个连接。
  • 对不起,我改一下。这就是我的意思。就像在 Chrome、隐身 Chrome 和 Firefox 打开的情况下,对于屏幕截图中打开的每个侦听器,这三个都从客户端代码中获取一次console.log

标签: node.js sockets coffeescript socket.io


【解决方案1】:

问题是由我的redis.on 'message' 监听器的位置引起的。我在我创建的每个套接字上都在听。实际上,我只需要在全局范围内收听它,然后向任何房间发送消息。这看起来像这样:

io.on 'connection', (socket) ->
  log.info "Connection established. [Socket: #{socket.id}]"

  socket.on 'join_room', (roomName) ->
    log.info "Join room '#{roomName}'. [Socket: #{socket.id}]"
    socket.join roomName

  socket.on 'disconnect', ->
    log.info "Connection destroyed. [Socket #{socket.id}]"

redis.on 'message', (redisChannel, message) ->
  message = JSON.parse message
  log.info "Room: #{message.room} - Event: #{message.event} - Message: #{message.message}"
  io.sockets.in(message.room).emit(message.event, message.message)

【讨论】:

    猜你喜欢
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    相关资源
    最近更新 更多