如何从默认命名空间发送到自定义命名空间?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从默认命名空间发送到自定义命名空间?相关的知识,希望对你有一定的参考价值。

我有一个使用Socket.io的React应用程序。我使用默认命名空间/和自定义命名空间/test。我需要能够从命名空间发送到另一个,但我只是设法让它从自定义到默认。

在客户端,事件监听器位于根(App.js)上:

componentDidMount() 
  socket.on('test_listener', (data) => 
    // Some code
  )

使用redux初始化连接:

import socketIOClient from 'socket.io-client';

const initialState = 
  initializeSocket: socketIOClient('http://localhost:3000/'),
  ...

在服务器端,这是代码:

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

  socket.on('something', (data) => 

    io.of('/test').emit('test_listener', data); // Not working
    socket.broadcast.emit('test_listener', data); // Is working

  )

);

我肯定知道io.of('namespace').emit('event_name', data);应该工作,因为它在Socket.io's Emit cheatsheet定居。客户端的事件监听器正在工作,因为我得到了broadcast.emit的东西。

另外,我可以使用以下代码从/test发射到/

socket.on('join_namespace_test', data => 

  // [...] Some code to check if the namespace exists

  io.of('/test').on('connection', function (nspSocket) 

    nspSocket.on('do_something', (data) => 
      io.of('/').emit('another_action', data); // This one is working fine
    )

  )

  // [...] Some code to add the user to the namespace /test (switching from default)

知道为什么从//test的排放不起作用?我没有得到任何错误,没有任何反应。


编辑:经过进一步研究,我发现了this post

您无法在现有连接上“切换”命名空间。在建立连接时连接到特定的命名空间,一旦建立连接,就无法更改。

为了确保问题不是来自项目的另一部分,我在小提琴上重现了这个问题。从默认发送到自定义的发送仍然不起作用,我还注意到当客户端从默认切换到自定义然后返回默认值时它会发出奇怪的行为(它会发送给发送方而不应该发送)。

因此,考虑到问题可能是客户端在默认命名空间和自定义命名空间之间切换而不是发射本身的方式,也许房间会是更好的选择吗?或者也许我应该找到一种方法在切换之前断开连接,但是建议吗?

答案

经过大量测试后,唯一有效的解决方案是在切换到另一个命名空间之前关闭先前的连接,然后再次调用套接字侦听器。当初始化broadcast时,它只能在命名空间/连接上设置。 socket.on

对于redux中的简单代码,解决方案可能如下所示(客户端,服务器端无需更改):

This post helped me to find the solution

作为旁注,在默认的var socket = io(); listen(); function switchNamespace(namespace) socket.close(); // Close the current connection socket = io(namespace); listen(); function listen() socket.on('test_listener', (data) => // Some code ) 内部或外部初始化io.of('/namespace').on('connection', ...没有任何区别。

在我们的例子中,这个解决方案不符合当前的项目结构,所以我们决定使用房间。

另一答案

你能告诉我客户端如何初始化连接?

它应该是这样的:

io.on('connection', ...

如果您在const socket = io('/test') 名称空间上广播某些内容,并且客户端收到它,则表示客户端连接到default名称空间而不是/名称空间。

在客户端,我很确定你不能在同一个套接字上监听多个命名空间。如果要这样做,则需要在客户端上初始化多个套接字:

/test

编辑

如果您只需要同时使用一个命名空间,那么您的其他响应很好。

但是,如果您想要一个真正的多命名空间处理,那么代码可能会更好一些:

const socketDefault = io()
const socketTest = io('/test')

以上是关于如何从默认命名空间发送到自定义命名空间?的主要内容,如果未能解决你的问题,请参考以下文章

如何将lodash直接导入JavaScript中的自定义命名空间

如何从另一个命名空间而不是全局命名空间定义函数和数据?

如何从默认 kops 命令更改 kubernetes 上下文中的默认命名空间?

如何防止从命名空间内访问类?

如何从命名空间导出,访问默认值? [复制]

如何从杰克逊 XML 解析中删除命名空间定义