netjs сокеты + websocket без socket.io

Я пытаюсь создать что-то вроде чата, используя 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, я получаю в узле сообщения CMD о "CONNECTED TO:" и "connected" и "I Chack Norris". После этого я пытаюсь написать в консоли браузера:

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

Также нет ошибок, но когда я пытаюсь эту строку:

conn.send('lol');

Я получаю сообщение об ошибке: "Uncaught DOMException: не удалось выполнить" send "на" WebSocket ": все еще в состоянии CONNECTING. (…)"

И через некоторое время я получаю еще одну ошибку: "Не удалось установить соединение WebSocket с" ws://localhost: 7001/": истекло время ожидания открытия WebSocket"

возможно, этот код неверен, но я перепробовал все, что нашел через гугл. Может кто-то помочь мне с этим?

Ответ 1

Если вы хотите создать свой собственный сервер webSocket, который может получать соединения webSocket из браузера, вам придется реализовать протокол webSocket на вашем сервере. Это не просто соединение сокетов. Он имеет последовательность запуска, которая начинается как HTTP-соединение, которое затем "обновляется" до протокола webSocket, включая обмен информацией о безопасности, а затем есть формат кадрирования webSocket для всех данных, отправленных через webSocket. Вы не просто отправляете обычный текст через webSocket.

Вы можете увидеть, как выглядит протокол webSocket здесь: Написание серверных веб-узлов. Если вы действительно не хотите создавать свой собственный сервер webSocket только для учебных целей, я бы действительно предложил вам получить существующий модуль, который выполнил всю работу с протоколом nitty gritty.

Затем библиотека socket.io строится поверх протокола webSocket, добавляя к ней дополнительные функции и формат сообщений.

Чтобы дать вам представление о подключении 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, который имеет формат кадрового формата данных:

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 для тестов keep-alive, и существует схема для больших пакетов и фрагментации, а клиент/сервер может согласовывать суб-протокол.