H11: Vestlusruum serveri ja klientrakenduse vahel

Täna loome serveri, mis töötab HTTP ja WebSocketiga, võimaldades saata sõnumeid ühendatud kasutajatele.

Loomine

Avame terminal ja luuame uus kaust

Seal avame VS code ja kirjutame kood

index.html

<!doctype html>
<form name="publish">
    <input type="text" name="message" maxlength="50"/>
    <input type="submit" value="Send"/>
</form>
 
<div id="messages"></div>
 
<script>
    let url = location.host == 'localhost' ?
        'ws://localhost:8080/ws' : location.host == 'javascript.local' ?
            `ws://javascript.local/article/websocket/chat/ws` : // dev integration with local site
            `wss://javascript.info/article/websocket/chat/ws`; // prod integration with javascript.info
    //создаем объект с вебсокетом
    let socket = new WebSocket(url);
 
    // отправляем сообщение на форму
    document.forms.publish.onsubmit = function() {
        let outgoingMessage = this.message.value;
 
        socket.send(outgoingMessage);
        return false;
    };
 
    // обрабатываем входящие сообщения
    socket.onmessage = function(event) {
        let incomingMessage = event.data;
        showMessage(incomingMessage);
    };
    //если пользователь закрыт сокет, то пишем об этом в консоли
    socket.onclose = event => console.log(`Closed ${event.code}`);
 
    // показываем сообщения в div#messages
    function showMessage(message) {
        let messageElem = document.createElement('div');
        messageElem.textContent = message;
        document.getElementById('messages').prepend(messageElem);
    }
</script>

index.js

const  ws = require('ws'); 
const http = require('http');
const fs = require('fs');

const wss = new ws.Server({ noServer: true });

function accept(req, res) {
  if (req.url === '/ws' && req.headers.upgrade &&
    req.headers.upgrade.toLowerCase() === 'websocket' &&
    req.headers.connection.match(/\bupgrade\b/i)) {
    wss.handleUpgrade(req, req.socket, Buffer.alloc(0), onSocketConnect);
  } else if (req.url === '/') { 
    fs.createReadStream({ path: './index.html' }).pipe(res);
  } else { 
    res.writeHead(404);
    res.end();
  }
}
const clients = new Set();

function onSocketConnect(ws) {
  clients.add(ws);
  
  ws.on('message', function(message) {
    message = message.slice(0, 50); 
    for (let client of clients) {
      client.send(message);
    }
  });

  ws.on('close', function() {
    console.log('connection closed');
    clients.delete(ws);
  });
}


let log;
if (!module["parent"]){
    log = console.log; 
    http.createServer(accept).listen(8080);
}
else {
    log = function() {}; 
    exports.accept = accept;

}

Siin me töötame nii WebSocketi kui ka HTTP-ga. Kui kasutaja külastab lehte, saadab server talle faili index.html. Kui keegi ühendub WebSocketi kaudu, võtab server vastu sõnumeid, piirab need 50 tähemärgiga ja saadab kõik sõnumid teistele ühendatud kasutajatele. Server töötab pordil 8080 ja haldab ühendusi: lisab need nimekirja ja eemaldab, kui ühendus suletakse.

käivitame seda terminalis ja vaatame tulemus