没有模块的 Nodejs websockets

lol*_*ail 2 websocket node.js

所以我试图在 nodejs 中制作一个没有任何非内置模块的 websocket 服务器(我的意思是像 socket.io 或 ws 这样的模块),当我用net.createConnection()它连接到它时工作正常,但我如何制作它以便我可以使用客户端 javascript 向/从服务器发送和接收数据,例如:

let ws = new WebSocket("ws://localhost:8000")
ws.onopen = () => {
    ws.send("sending data")
}
Run Code Online (Sandbox Code Playgroud)

任何例子将不胜感激

jfr*_*d00 5

webSocket 连接有它自己的连接方案(从 http 连接开始)、从 http 到 webSocket 协议的升级方案、它自己的安全协商方案和它自己的数据格式,并且随着时间的推移规范中出现了一些变化,这意味着您可能必须支持多个版本才能支持所有客户端。要实现 webSocket 服务器,您必须实现所有这些。

原始协议在这里定义:https : //tools.ietf.org/html/rfc6455

简而言之:

  1. 每个 webSocket 连接都以一个 http 请求开始,该请求包含一些自定义标头,表明它是“升级”到 webSocket 协议的请求。该初始请求还包含一个安全密钥和一个安全版本号。

  2. 如果服务器接受升级到 webSocket 协议,它会用另一个安全密钥发回响应。

  3. 在确认之后,客户端或服务器可以开始使用 webSocket 数据帧数据包格式和使用适当的安全密钥向另一端发送数据包。

例子:

客户端发送:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
Run Code Online (Sandbox Code Playgroud)

服务器响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Run Code Online (Sandbox Code Playgroud)

并且,从MDN 中了解数据框的外观:

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 ...                |
+---------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

您可以在这些其他答案中看到有关协议如何的一些其他讨论:

nodejs 网络套接字 + 没有 socket.io 的 websocket

websocket 实现是否在内部使用 http 协议?

WebSocket 和普通套接字通信有什么区别?

除非这是出于学习原因的纯粹学术练习,否则重新实现低级协议是一种非常非常低效的使用开发人员时间的低级协议,而该协议已经存在标准的、经过良好测试的开源实现。您将花费大量时间在低级位处理和与不同客户端实现的兼容性测试上,然后随着标准的发展而花费更多时间进行维护。

  • @JCollier - 不是我自己做的事情。来自 [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers)。 (2认同)