Reputation: 124
So I'm trying to make a websocket server in nodejs without any non-built-in modules (I mean modules like socket.io or ws), when I connect to it with net.createConnection()
it works fine, but how do I make it so that I can send and recieve data to/from the server by using Client-Side javascript like:
let ws = new WebSocket("ws://localhost:8000")
ws.onopen = () => {
ws.send("sending data")
}
Any examples would be very much appreciated
Upvotes: 3
Views: 1389
Reputation: 707328
A webSocket connection has it's own connection scheme (that starts with an http connection), an upgrade scheme from http to the webSocket protocol, it's own security negotiation scheme and its own data format and there have been some variations in the spec over time which means you might have to support several versions to support all clients. To implement a webSocket server, you have to implement all of that.
The raw protocol is defined here: https://www.rfc-editor.org/rfc/rfc6455
In a nutshell:
Every webSocket connection starts with an http request that contains a few custom headers that indicate it's a request to "upgrade" to the webSocket protocol. That initial request also contains a security key and a security version number.
If the server accepts the upgrade to the webSocket protocol, it sends back a response with another security key.
Upon acknowledgement, at that point, either the client or server can start sending packets to the other side using the webSocket data frame packet format and using the appropriate security keys.
Example:
Client sends:
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
Server responds:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
And, an idea how the data frame looks from 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 ... |
+---------------------------------------------------------------+
You can see some other discussions of how the protocol is in these other answers:
nodejs net sockets + websocket without socket.io
Do websocket implementations use http protocol internally?
What's the difference between WebSocket and plain socket communication?
Unless this is a purely academic exercise for learning reasons, it's a really, really inefficient use of your developer time to re-implement a low level protocol for which standard, well-tested, open-source implementations already exist. You will spend a lot of time on low level bit twiddling and on compatibility testing with different client implementations and then more time on maintenance as the standard evolves over time.
Upvotes: 8