Utiliser websocket avec Express, Node.js et la librairie Ws

11/01/2018
écrit par: ddtraceweb

Utiliser les websockets pour créer plusieurs channel à la volée et y diffuser des informations, c'est ce que nous allons voir ici.

Etape 0 : Configurer votre serveur web (nginx pour ma part) pour recevoir des header de type "Upgrade" afin de permettre le websocket :

 

proxy_set_header   Upgrade $http_upgrade;
proxy_set_header   Connection "upgrade";
proxy_set_header   Host $http_host;

 

1. code coté frontend afin de se connecter au serveur de websocket, se connecter au channel user et y diffuser un message.

<html>
<body>
<h4>websocket</h4>
<h5>Group: <span id="group">darwin</span></h5>
<!-- a hardoced group name -->
<button onclick="bjoin();">join group</button><br>
<input id="text" type="text"/>
<span id="out"></span>
<script>

    var group=document.getElementById("group").textContent;

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

	ws.onerror=function(e){out.innerHTML=e;}
	ws.onclose=function(e){out.innerHTML='closed'+e;}

	ws.onopen=function() {
		out.innerHTML='connected ';
	}

	ws.onmessage=function(ms)
	{
		out.innerHTML+=ms.data+'<br>';
	}

	function send(msg){
		ws.send(JSON.stringify({msg:msg}));
	}

	function broadcast(msg,userId){
		ws.send(JSON.stringify({userId:userId,msg:msg}))
	}

	function joinUser(userId){
		ws.send(JSON.stringify({joinUser: userId}));
	}

	function bjoin(){
		//alert(group);
		joinUser(group);
	
		text.onchange=function(el){
		//alert(el.target.value);
			broadcast(el.target.value,group);
		}
	}
</script>
</body>
</html>

 

2. Code coté Back-end node.js pour créer le serveur websocket et diffuser les messages typés.

 

'use strict';

let WSServer = require('ws').Server;
let WS = require('ws');
let app = require('./src/setup').app;
let server = require('http').createServer();

// Create web socket server on top of a regular http server
let wss = new WSServer({

  server: server
});

// Broadcast to all.
wss.broadcast = function broadcast(message) {
  wss.clients.forEach(function each(client) {
    if (client.readyState === WS.OPEN) {
      //client.send(message);
      if(client.userId.indexOf(JSON.parse(message).userId)>-1){
        client.send(message);
      }

      if(client.threadId.indexOf(JSON.parse(message).threadId)>-1){
        client.send(message);
      }
    }
  });
};

// On monte l'app express
server.on('request', app);

wss.on('connection', function connection(ws) {

  ws.userId=[]; //liste des channels users

  ws.threadId=[]; //liste des channels threads

  ws.on('message', function incoming(message) {

    console.log(`received: ${message}`);

    let data =JSON.parse(message);

    if(data.joinUser) // joindre le tableau des users en envoyant son userId
    {
      //message attendu : {joinUser: userId}
      ws.userId.push(data.joinUser);
    }

    if(data.userId) // envoyer un message à un user
    {
      //message attendu : {userId: userId, msg: msg}
      wss.broadcast(message);
    }

    if(data.joinThread) // joindre le tableau des threads en envoyant son threadId
    {
      //message attendu : {joinThread: threadId}
      ws.threadId.push(data.joinThread);
    }

    if(data.threadId) // envoyer un message à un thread
    {
      //message attendu : {threadId: threadId, msg: msg}
      wss.broadcast(message);
    }

    ws.send(JSON.stringify({

      answer: 42
    }));

  });

  ws.on('error',function(e){ return console.log(e);});
  ws.on('close',function(e){ return console.log('websocket closed'+e);});
});


server.listen(app.get('port'), function () {
  console.log('status', {msg: 'env ' + app.get('env')});
  server.emit('ready');
});

3. Envoyer un message depuis l'api Express, il vous suffit de faire la chose suivante :

 

let WSocket = require('ws');

let wss = new WSocket('ws://localhost');

wss.on('open', function() {
   wss.send(JSON.stringify(_cmt));
});