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));
});