EADDRINUSE 错误,用于在不同路径上打开 websocket 但在 nodejs 中的相同端口

Posted

技术标签:

【中文标题】EADDRINUSE 错误,用于在不同路径上打开 websocket 但在 nodejs 中的相同端口【英文标题】:EADDRINUSE error for opening websocket on different path but same port in nodejs 【发布时间】:2018-03-29 12:47:14 【问题描述】:

我正在基于 nodejs 中的 ws websockets 创建一个多房间聊天应用程序。我可以让单个聊天室工作,但在创建第二个房间时,我收到 EADDRINUSE 错误。错误是因为我已经为第一个房间使用了 websocket 端口。如何在不同路径的同一端口上创建第二个房间。

例如:

var WebSocketServer = require('ws').Server;
a = new WebSocketServer(port:8080, path:'/a'), 
b = new WebSocketServer(port:8080, path:'/b');

这给出错误:错误:监听 EADDRINUSE 8080

谢谢, 罗宾

【问题讨论】:

【参考方案1】:

这里的问题是每个WebSocketServer 为HTTP 服务器上的升级事件添加了一个新的监听器,当该事件发出时,所有服务器上都会调用handleUpgrade。 这是因为路径验证关闭了路径 mismatch 上的连接。

您使用它们的方式,对于网络套接字的同一端口上的不同路径不是一个好主意,因为在您的情况下,与something.com/a 的连接将首先在a 上建立,然后由b 关闭因为他们都写在同一个套接字上。

为了拥有多个 WebSocket 服务器和只有一个共享的 HTTP 服务器,开发人员可以使用这样的东西:

const wss1 = new WebSocket.Server( noServer: true );
const wss2 = new WebSocket.Server( noServer: true );
const server = http.createServer();

server.on('upgrade', (request, socket, head) => 
  const pathname = url.parse(request.url).pathname;

  if (pathname === '/a') 
    wss1.handleUpgrade(request, socket, head, (ws) => 
      wss1.emit('connection', ws);
    );
   else if (pathname === '/b') 
    wss2.handleUpgrade(request, socket, head, (ws) => 
      wss2.emit('connection', ws);
    );
   else 
    socket.destroy();
  
);

【讨论】:

如果不同路径(聊天室)的数量是动态的会发生什么。在这个例子中我刚刚提到了两个聊天室,如果我在同一个 websocket 端口上有多个路径会发生什么? 我不认为这是否会成为现实生活中的问题(拥有动态聊天室),因为您将始终知道您的应用程序支持哪些聊天室以及支持多少聊天室。您可以随时使用ifswitch 在该连接上发出信号。正确的 ?有意义吗?

以上是关于EADDRINUSE 错误,用于在不同路径上打开 websocket 但在 nodejs 中的相同端口的主要内容,如果未能解决你的问题,请参考以下文章

Nodejs & socket io:警告 - 引发错误:错误:监听 EADDRINUSE

错误:路径 '/var/.../default.realm' 的领域已经在当前线程上以不同的模式打开

当量角器无法找到元素时,获取 EADDRINUSE 连接 EADDRINUSE

未捕获的错误:在 mocha 单元测试时监听 EADDRINUSE:地址已在使用 :::3000

Nodemon:错误:监听 EADDRINUSE:地址已在使用 :::5000

节点:事件:304 错误:监听 EADDRINUSE:地址已在使用 :::5000