Будучи новичком в WebSocket, я нашел много хороших ресурсов в Интернете, большинство из которых содержат отличные демонстрации.
Но демоверсии содержат много кода оптимизации или логического кода, которые служат псевдоцелям демо-приложения. Я думаю, что демонстрация, более похожая на скелет, была бы лучше для новичка? Я пытался сделать это так, и надеюсь, что это может помочь.

Полный источник: https://github.com/JilinXie/ChatRoom

Веб-сокет

Я предполагаю, что у вас есть основное представление о том, что такое WebSocket. Если вы этого не сделаете, это протокол, который позволяет вам общаться из браузера на сервер через TCP.

Демонстрация WebSocket/ws

Прежде чем мы начнем, давайте сделаем демонстрацию, показывающую, как браузер и сервер могут передавать привет через TCP。
Git: https://github.com/JilinXie/ChatRoom/tree/master/WebSocketTut/v1_sayhi

  1. Сервер:

Мы используем Node.js и WebSocket/ws

npm init
npm install --save ws

Запустите указанную выше команду в пустой папке. Мы используем WebSocket/ws lib для сборки сервера. Что может быть так просто, как:

//server.js
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({port: 9090});
wss.on('connection', function(connection) {
    connection.on('message', function(raw_msg){
        console.log(raw_msg);
        connection.send("world");
    }
};

Поместите его в server.js и запустите node server.js.

2. Страница клиента:

<!-- client.html -->
<script>
    var signalChannel = new WebSocket("ws://localhost:9090");
    signalChannel.onmessage = function(raw_msg) {
    console.log(raw_msg.data);
}
signalChannel.onopen = function() {
    signalChannel.send("hello");
}
</script>

Откройте client.html в браузере и откройте консоль:

Вы должны увидеть «world» в консоли браузера и «hello» в выводе узла.

Чат «Протокол»

Давайте определим, как клиент и сервер взаимодействуют (в формате JSON):

  1. Вход:
    Пользователь отправляет операцию входа на сервер. Сервер Храните имя пользователя и его соединение до закрытия соединения.
  2. ListUser:
    Когда новый пользователь входит в систему. Сервер должен транслировать его всем.
  3. Разговор:
    пользователь может выбрать разговор со «всеми» или с коллегой. Сервер передает информацию.
Login:
cli -> server
    {"operation": "login", 
     "data": {"username": USERNAME(STRING)}}
server -> cli
    {"operation": "login", 
     "data": {"state": STATE(BOOL)}}
ListUser:
server -> cli
    {"operation": "listuser", 
     "data": {"usernames": USERNAMES(LIST)}}
Talk:
cli -> server// if peername is empty, content is broadcasted.
      {"operation": "talk",
       "data": {"peername": PEERNAME(STRING), 
                "content": CONTENT(STRING)}}
server -> cli
    {"operation": "talk", 
     "data": {"talker": TALKER(STRING), 
              "content": CONTENT(STRING)}}

Сервер ChatRoom и клиентская среда.

Как показано в «Демонстрации WebSocket/ws», браузер и сервер используют метод «send» и обратный вызов «onmessage» для выполнения связи. Итак, структура нашей клиентской страницы и сервера должна быть примерно такой:

  1. Страница клиента:
    Кстати, мы добавим несколько фиктивных тегов на страницу, которые позже могут содержать содержимое чата.
<!DOCTYPE html>
<html>
<!-- username shown to other peers -->
<label> UserName: </label> <input type="text" id="username">
<button> login </button>
<br>
<!-- list of all other peers -->
<ul id="userlist">
</ul>
<!-- peer name to talk to (empty to talk to all) -->
<label> PeerName (broadcast if null)</label><input type="text" id="peername">
<br>
<!-- chat here -->
<textarea id="writeboard" style="width:300px;height:200px;"></textarea>
<button> send </button>
<br>
<!-- board showing other's saying -->
<textarea id="chatboard" style="width:300px;height:200px;" readonly></textarea>
<script>
var signalChannel = new WebSocket("ws://localhost:9090");
signalChannel.onmessage = function(raw_msg) {
    let msg = {};
    try {
        msg = JSON.parse(raw_msg.data);
    } catch(e) {
        console.log("Invalid msg format");
        return;
    }
    switch (msg.operation) {
        case "login":
            //handle login;
            break; 
        case "listuser":
            //handle list user;
            break;
        case "talk":
            //handle talk;
            break;
        default:
            break;
    }
}
</script>
</html>
</html>

2. Как выглядит сервер.

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({port: 9090});
wss.on('connection', function(connection) {
    connection.on('message', function(raw_msg) {
        let msg = {};
        try {
            msg = JSON.parse(raw_msg);
        } catch(e) {
            console.log("Invalid message format: " + raw_msg);
            return;
        }
        switch(msg.operation) {
            case "login":
                //handle user login
                //broadcast new user
                break;
            case "talk":
                //handle talk
                break;
            default:
                break;
        }
    });
});

Теперь вы можете запустить сервер node server.js и открыть файл client.html напрямую в браузере.

Внедрите «протокол» ChatRoom

  1. Используйте JSON
    Все сообщения, отправляемые клиентами и сервером, имеют формат JSON.

клиент

function sendMsg(msg) {
    signalChannel.send(JSON.stringify(msg));
}

сервер

function sendMsg(connection, msg) {
    connection.send(JSON.stringify(msg));
}

2. Войти
Каждый клиент установил соединение с сервером после загрузки страницы, на var wss = new WebSocketServer({port: 9090}); . По логину сервер привязывал соединение с никнеймом.

клиент

<button onclick="login()"> login </button>
......
function login() {
    let username = document.getElementById("username").value;
    let command = {operation: "login",
                   data: {username: username}};
    sendMsg(command);
}
......
switch (msg.operation) {
    case "login":
        login();
        break;
    ...
}

сервер

var users_db = {};
function login(connection, username) {
    users_db[username] = connection;
}
.......
switch(msg.operation) {
    case "login":
        login(connection, msg.data.username);
        break;
    ......
}

3. сервер userlist
, транслирует список имен пользователей всем остальным.

function broadcast_newuser() {
    let usernames = Object.keys(users_db);
    for (let username in users_db) {
        sendMsg(users_db[username],
                {operation: "listuser", 
                 data: {usernames: usernames}});
    }
}

клиент, получить и обновить список пользователей ‹ul›

function update_userlist(usernames) {
    let userlist = document.getElementById("userlist");
    userlist.innerHTML = "";
    for (let i in usernames) {
        userlist.innerHTML += "<li>" + usernames[i] + "</li>";
    }
}
......
switch(msg.operation) {
    ......
    case "listuser":
         update_userlist(msg.data.username);
         break;
    ......
}

И теперь вы можете запустить node server.js и открыть несколько client.html в своем браузере, войти на каждую страницу с другим именем. Они увидятся в ‹ul›.

4. Обсуждение
Итак, это последний шаг к тому, чтобы сделать этот материал немного полезным. Заставьте их обмениваться сообщениями через сервер.
Здесь мы поместим только реализацию трансляции.

клиент

<button onclick="talk()"> send </button>
......
function talk() {
    let text = document.getElementById("writeboard").value;
    if (text === "") {
        alert("nothing to send");
        return;
    }

    let command = {operation: "talk",
                   data: {peername: '',
                          content: text}}
document.getElementById("writeboard").value = "";
    sendMsg(command);
}
......
function update_chatboard(content, username) {
    let chatboard = document.getElementById("chatboard");
    chatboard.value += username + ": " + content + '\n';
}
switch(msg.operation) {
    ......
    case "talk":
         update_chatboard(msg.data.content, msg.data.talker);
         break;
}

server
При получении голосового сообщения от клиента транслируйте сообщение и имя пользователя всем клиентам.

function _who_am_i(connection) {
    for (let uname in users_db) {
        if (connection.id === users_db[uname].id) {
            return uname;
        }
    }
    return '----';
}
function broadcast_talk(content, talker) {
    for (let username in users_db) {
        sendMsg(users_db[username],
                {operation: "talk",
                 data: {content: content,
                        talker: talker}})
    }
}
......
switch(msg.operation) {
    ......
    case "talk":
        broadcast_talk(msg.data.content, _who_am_i(connection))
        break;
    ......
}

Теперь вы можете общаться между клиентами
Вы можете проверить https://github.com/JilinXie/ChatRoom/tree/master/WebSocketTut/v2_talk
, чтобы получить код.
/> Где client_frame.html и server_frame.js — это источник ChatRoom Server and Client Framework, а client.html и server.js — это источник реализации протокола чата.

Ну наконец то:

Приведенный здесь код предназначен для иллюстрации основных вещей, которые помогут новичкам разобраться. Я пытался избавиться от логики, не связанной с websocket.
Но вы можете проверить https://github.com/JilinXie/ChatRoom для оптимизированной версии.

Ура~ Я опубликовал свою первую статью :D.