Nodejs websocket 连接 socket.io问题

Nodejs websocket 连接 socket.io问题

客户端: var url = “ws://localhost:8088”; w = new WebSocket( url ); //事件监听 w.onopen = function() { console.log(“open”); } w.onclose = function(e) { console.log( “closed” ); }

服务端: var socket = require( ‘socket.io’ ); var io = socket.listen( 8088 ); io.set(‘log level’, 1); io.sockets.on(‘connection’, function ( socket ) { console.log( socket ); });

WebSocket connection to ‘ws://localhost:8088/’ failed: Connection closed before receiving a handshake response 为什么在握手前就断开连接了?


9 回复

在使用 socket.ioWebSocket 进行通信时,如果遇到“WebSocket connection to ‘ws://localhost:8088/’ failed: Connection closed before receiving a handshake response”的错误,这通常意味着客户端与服务器之间的握手过程没有成功完成。以下是一些可能的原因和解决方案。

可能的原因

  1. 不匹配的协议版本:客户端使用的是标准的 WebSocket 协议(ws://),而 socket.io 默认使用自己的协议,这可能导致握手失败。
  2. 缺少 socket.io-client:客户端需要安装并使用 socket.io-client 而不是原生的 WebSocket API。
  3. 端口或路径配置错误:确保客户端和服务器使用的端口和路径一致。

解决方案

1. 安装 socket.io-client

首先,确保客户端使用 socket.io-client 而不是原生的 WebSocket API。

npm install socket.io-client

2. 修改客户端代码

使用 socket.io-client 来建立连接:

const io = require('socket.io-client');
const socket = io('http://localhost:8088');

socket.on('connect', () => {
    console.log("Connected");
});

socket.on('disconnect', () => {
    console.log("Disconnected");
});

3. 服务端代码

确保服务端正确地设置了 socket.io

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

io.set('log level', 1); // 减少日志输出

io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);
    
    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
    });
});

server.listen(8088, () => {
    console.log('Server is running on port 8088');
});

解释

  • 客户端:使用 socket.io-client 建立连接,并监听 connectdisconnect 事件。
  • 服务端:使用 socket.io 监听连接事件,并打印连接和断开连接的日志信息。

通过这种方式,可以确保客户端和服务器之间使用相同协议进行通信,从而避免握手失败的问题。


是socket.io不走WS协议?

用socket.io-client. websocket只是socket.io实现业务封装的一个浏览器方面的backend, 类比的话, websocket是tcp, 而socket.io是http, 后者固然基于前者, 但是你也必须按照socket.io约定的protocol走.

@ 514366607 你搞定了么?如何解决的,我也遇到这个问题了

在客户端如果用Socketio方式就可以,换成html5的websocket方式就死活不行,崩溃ing…

不好意思,挖坟啦。

我也自己写原生客户端的websocket,也是同样的报错,lz怎么解决的?

socket.io socket.io-client版本还得对应,最好完全匹配

请问这个问题最终解决了么。 我这也是客户端用的WebSocket,服务端用的Socket.IO,想知道咋串起来。

牛头不对马嘴

你的问题在于客户端和服务器端使用的是不同的WebSocket库。客户端使用的是浏览器内置的WebSocket API,而服务器端使用的是Socket.IO。这两个库并不是直接兼容的。

示例解决方案

客户端使用标准 WebSocket API

如果你希望继续使用标准的 WebSocket API,你需要确保服务端也提供标准的 WebSocket 服务。这可以通过 ws 库来实现。

客户端代码:

var url = "ws://localhost:8088";
var w = new WebSocket(url);

w.onopen = function () {
    console.log("open");
};

w.onclose = function (e) {
    console.log("closed");
};

服务端代码(使用 ws 库):

首先安装 ws 库:

npm install ws

然后使用 ws 库来创建 WebSocket 服务器:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8088 });

wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
        console.log('received: %s', message);
    });

    ws.send('something');
});

console.log('WebSocket server is running on ws://localhost:8088');

使用 Socket.IO

如果你希望继续使用 Socket.IO,那么客户端也需要使用 Socket.IO 的客户端库。

客户端代码:

<!DOCTYPE html>
<html>
<head>
    <title>Socket.IO Test</title>
    <script src="/socket.io/socket.io.js"></script>
</head>
<body>
    <script>
        var socket = io('http://localhost:8088');

        socket.on('connect', function () {
            console.log('connected');
        });

        socket.on('disconnect', function () {
            console.log('disconnected');
        });
    </script>
</body>
</html>

服务端代码:

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);

app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
    console.log('a user connected');

    socket.on('disconnect', () => {
        console.log('user disconnected');
    });
});

http.listen(8088, () => {
    console.log('listening on *:8088');
});

确保客户端能够加载到 socket.io.js 文件,并且通过 HTTP 请求访问服务端。这样可以避免握手失败的问题。

回到顶部