Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Socket.io“;无效的帧头“;独立websocket服务器出错_Node.js_Websocket_Socket.io_Apollo Server_Engine.io - Fatal编程技术网

Node.js Socket.io“;无效的帧头“;独立websocket服务器出错

Node.js Socket.io“;无效的帧头“;独立websocket服务器出错,node.js,websocket,socket.io,apollo-server,engine.io,Node.js,Websocket,Socket.io,Apollo Server,Engine.io,有没有办法让一个单独的websocket服务器与另一条路径上的socket.io一起工作 let http = require('http'); let express = require('express'); let socketio = require('socket.io'); let websocket = require('ws'); let httpServer = http.createServer(); let expressApp = express(); httpSer

有没有办法让一个单独的websocket服务器与另一条路径上的
socket.io
一起工作

let http = require('http');
let express = require('express');
let socketio = require('socket.io');
let websocket = require('ws');

let httpServer = http.createServer();

let expressApp = express();
httpServer.on('request', expressApp);

let socketioServer = socketio(httpServer, { path: '/aaaaa/socket.io/' });
socketioServer.of('/').on('connect', () => {});

let websocketServer = new websocket.Server({ server: httpServer, path: '/aaaaa/graphql' });

httpServer.listen(2233, () => console.log('started'));
我看到的行为是,当创建一个单独的websocket服务器时,
socket.io仍能正常工作,但不会升级到websocket的连接,并出现错误(来自chrome):

需要说明的是,如果省略websocket服务器行,
socket.io
工作正常

我的具体使用案例是,当启用订阅时,
apollo server express
包创建websocket服务器。有没有办法以更友好的方式配置
socket.io
?或者,我相信我可以提供一个websocket服务器供apollo使用,而不是创建一个。。。我将如何创建它

复制的软件包版本:

node       8.11.1
express    4.16.4
socket.io  2.1.1
ws         6.1.0

如果这对其他人有帮助,以下是我的衍生解决方案:

let [socketioUpgradeListener, apolloUpgradeListener] = httpServer.listeners('upgrade').slice(0);
httpServer.removeAllListeners('upgrade');
httpServer.on('upgrade', (req, socket, head) => {
  const pathname = url.parse(req.url).pathname;
  if (pathname == '/aaaaa/socket.io/')
    socketioUpgradeListener(req, socket, head);
  else if (pathname == '/aaaaa/graphql')
    apolloUpgradeListener(req, socket, head);
  else
    socket.destroy();
});
这有点烦人,因为在我搞乱它们之前,这两个库已经完全初始化了它们的websocket服务器,有很多事件侦听器。但是,我可以选择
“升级”
侦听器并手动委派它们。当然,这并不完美,因为它对初始化顺序和新的侦听器很敏感,但对于我的用例来说已经足够了


如果此解决方案存在任何明显的缺陷或websocket服务器委派的任何其他细微差别,请告诉我。

在并行使用
graphql
-和
socket.io模块时,在
NestJs
中也存在同样的问题。作为Trevor解决方案的替代方案,您可以将
socket.io
绑定到另一个端口,并使用像nginx这样的反向代理来解析路径

app.gateway.ts

@WebSocketGateway(3001)
export class AppGateway implements OnGatewayConnection {   

  handleConnection(
    client: any,
    payload: any
  ) {
    client.emit('Hi from port 3001');
  }
}
nginx.conf

server {
        listen 80;
        listen [::]:80;
        server_name localhost;

        location /graphql {
                proxy_pass http://127.0.0.1:3000;
        }

        location /socket.io {
                proxy_pass http://127.0.0.1:3001/socket.io/;

                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;

                proxy_http_version 1.1;
        }
}

当然,您可以跳过最后一部分,通过客户端上的
ws://localhost:3001/socket.io
直接连接到套接字。

这不是应该实现的。我想要一个socket.io客户端连接到socket.io服务器,我想要一个websocket客户端连接到websocket服务器。我不是在寻求交流。啊,我当时误解了。所以问题是,
ws
不会将路径
/aaaaa/socket.io
上的套接字连接委托给
socket.io
?看起来要让
ws
发挥作用,您必须让服务器根据路径委托给websocket服务器或socket.io,到/aaaaa/graphql的websocket连接看起来非常好,只是socket.io端无法连接upgrade@PatrickRoberts嘿,成功了!这并不像那个链接那样简单,但手动处理升级事件才是关键。非常感谢你!我不知道你是如何找到这个解决方案的,但我和PeerJS和SocketIO有过同样的问题,后来我搬到Primus找到了同样的问题。对于我的primus和peerjs应用程序,您的解决方案对完全相同的问题非常有效。我当然很想知道你是如何找到这个解决方案的。@Sameer帕特里克·罗伯茨在上面的评论中给出的链接让我走上了正确的道路
server {
        listen 80;
        listen [::]:80;
        server_name localhost;

        location /graphql {
                proxy_pass http://127.0.0.1:3000;
        }

        location /socket.io {
                proxy_pass http://127.0.0.1:3001/socket.io/;

                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;

                proxy_http_version 1.1;
        }
}