3

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

lolfail
  • 124
  • 2
  • 12
  • @RolandStarke Already saw it, read a couple things but the point is that I'm trying to do it without additional modules – lolfail Mar 05 '20 at 18:00
  • @RolandStarke yeah suro no problem I'll read it and try to implement it – lolfail Mar 05 '20 at 19:15
  • @RolandStarke thanks, I read it, now i got it to connect, now I just need to figure out a couple of things and sould be done – lolfail Mar 05 '20 at 21:11

1 Answers1

6

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:

  1. 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.

  2. If the server accepts the upgrade to the webSocket protocol, it sends back a response with another security key.

  3. 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.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • You ASCIIed the bits of the data frame? This answer deserves applause and fireworks. – JCollier Mar 24 '21 at 00:25
  • 2
    @JCollier - Not something I did myself. that came from [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers). – jfriend00 Mar 24 '21 at 02:06