javascript - 没有socket.io的nodejs net sockets + websocket

标签 javascript node.js sockets websocket

我正在尝试使用 nodejs 创建类似聊天的内容。 我是 nodejs 的新手,我想在没有 socket.io 的情况下创建它(我想了解它是如何工作的)。 这是我正在使用的代码。

var http = require('http');
var net = require('net');


var server = http.createServer(function(req,res){

    res.writeHead(200,{'content-type' : 'text/html'});
    res.write('<a href="./lol/">lol</a><br>');
    res.end('hello world: '+req.url);



    var client = new net.Socket();
    client.connect('7001', '127.0.0.1', function() {

        console.log('CONNECTED TO: ');
        // Write a message to the socket as soon as the client is connected, the server will receive it as message from the client 
        client.write('I am Chuck Norris!');

    });

    // Add a 'data' event handler for the client socket
    // data is what the server sent to this socket
    client.on('data', function(data) {

        console.log('DATA: ' + data);
        // Close the client socket completely
        client.destroy();

    });

    // Add a 'close' event handler for the client socket
    client.on('close', function() {
        console.log('Connection closed');
    });
    //req.

});
server.listen(7000);


require('net').createServer(function (socket) {
    console.log("connected");

    socket.on('data', function (data) {
        console.log(data.toString());
    });
}).listen(7001);

一切正常,(我认为)。 当我打开 localhost:7000 时,我收到有关“连接到:”和“已连接”和“我是查克诺里斯”的 Node CMD 消息。 之后我尝试在浏览器控制台中编写:

var conn = new WebSocket('ws://localhost:7001/');

也没有错误,但是当我尝试这一行时:

conn.send('lol');

我收到一个错误:“未捕获的 DOMException:无法在 'WebSocket' 上执行 'send':仍处于 CONNECTING 状态。(...)”

一段时间后我又收到一个错误:“WebSocket connection to 'ws://localhost:7001/' failed: WebSocket opening handshake timed out”

也许这段代码是错误的,但我已经尝试了通过谷歌找到的所有内容。有人可以帮我解决这个问题吗?

最佳答案

如果您想创建自己的 webSocket 服务器来接收来自浏览器的 webSocket 连接,您必须在您的服务器上实现 webSocket 协议(protocol)。它不仅仅是一个简单的套接字连接。它有一个启动序列,以 HTTP 连接开始,然后“升级”到 webSocket 协议(protocol),包括安全信息的交换,然后有一个 webSocket 帧格式用于通过 webSocket 发送的所有数据。您不只是通过 webSocket 发送纯文本。

您可以在这里看到 webSocket 协议(protocol)的样子:Writing Websocket Servers .除非您真的想制作自己的 webSocket 服务器只是为了学习,否则我真的建议您获取一个已经为您完成所有基本协议(protocol)工作的现有模块。

socket.io 库随后构建在 webSocket 协议(protocol)之上,在此之上添加了额外的功能和消息格式。

为了让您了解 webSocket 是如何连接的,下面是一个典型的连接顺序:

浏览器发送连接请求:

GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

服务器响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

然后,双方切换到 webSocket 协议(protocol),其数据帧格式如下:

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

此外,还有用于保活测试的 ping 和 pong 数据包,以及用于大数据包和分片的方案,客户端/服务器可以协商子协议(protocol)。

关于javascript - 没有socket.io的nodejs net sockets + websocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32808988/

相关文章:

node.js - 使用 Passport-facebook 策略的 2 个实例

javascript - mongo near 将 maxDistance 设置为集合中的值

java - 从移动设备到 PC 的 UDP 多播

javascript - Cordova iOS : Failed to load resource: The requested URL was not found on this server

javascript - joi:不返回自定义错误,abortEarly 设置为 false

javascript - 如何在 WordPress `functions.php` 中将一个又一个脚本排队,并让它们一起工作?

javascript - 在 Openshift 上热部署 node.js 应用程序时究竟发生了什么?

javascript - http-proxy 总是挂掉

java - C客户端与Java服务器通信错误

Javascript/jQuery 区分移动设备和 PC