WebSocket Demo

Server and client code for exchanging text and images between the server and the browser via WebSocket.

Typically, WebSocket passes strings of characters, even if some frameworks seem to pass more complex objects, they do so using background transformations. To pass an object, it is placed directly in quotation marks to make it a string, or the stringify method is used. Both are used in demos that use server-side node.js and the server-side WebSocket framework, while the standard WebSocket object is used on the browser side.

This demo is minimalistic, sending multiple messages between the browser and the file system, local or remote, and passing an image to be displayed in the canvas tag. This gives basic code that can be easily extended for a real application. It is more suitable for local applications or controlling a robot from a computer or mobile (the section on electronic mounts shows how to implement it in practice).

Node.js is installed on the server, and then nodejs-websocket:

node npm nodejs-websocket

It can also be ws, or socketjs, which also provides a connection between browsers or any other library. Socket.io becomes difficult to install, I would not adhere to such an introduction, but it may be suitable for web applications.

The client and server exchange shape objects:

{ "text" : "...un message..." }

or

{ "image" : "...chemin de l'image sur le serveur..." }

Another option is to exchange somewhat more complex objects with the "type" property, as the Xul.fr demonstration does, and the type is "text" or "image."

In either case, the object is converted to a character string before being passed, and decrypted by the JSON parse method upon receipt.

Server ID

var ws = require("nodejs-websocket")
var fs = require("fs")

var server = ws.createServer(function (connect) {
  console.log("Server started...")
   
  connect.on("text", function (str) {
     var jobj = JSON.parse(str);
     if("text" in jobj) {
         console.log("Received: " + jobj["text"])
         connect.sendText('{ "text": "Server connected to browser."}')
         return;
     }
     if("image" in jobj) {  
         console.log("Image asked.")
         var path ="house.png";        // for this demo, only one image
         console.log("Sending image: " + path);
         fs.exists(path, function(result) {
              var data = JSON.stringify( {'image' : path } );
              connect.sendText(data); 
         });
         return;
        }
    })

    connect.on("close", function (code) {
        console.log("Browser gone.")
    })
});

server.listen(8100)

As you can see in the case of an image, the server checks for a file and simply sends the local path to the image. We will see in the client code what is enough for the browser .

The image path must be relative to the page path, not on the local file system, otherwise the Chrome browser will drop the assignment.

JavaScript client code

 var socket = new WebSocket("ws://localhost:8100");
  var canvas;
  var inner;
  window.onload=function() {
    canvas = document.getElementById("mycanvas");
    inner = document.getElementById("inner");
  }
  
  var image = new Image();
  
  function processImage(imagePath)  {       
    image.onload = function ()
    {
      // le code de l'ajustement de la taille d'image est dans l'archive
       var context = canvas.getContext("2d");
       context.scale(scalew, scaleh);
       context.drawImage(image, 0, 0);

       // on affiche le nom du fichier et les dimensions de l'image
       var message = imagePath + ", " + ow + " x " + oh + " px";
       if(w < ow || h < oh)
        message += ", resized to " + w.toFixed() + " x "+ h.toFixed();
       document.getElementById('storage').innerHTML = message;
     }
  }

  socket.onopen = function (event) {
    socket.send('{ "text": "Browser ready!"}' ); 
  };

  socket.onmessage=function(event) { 
    var command = JSON.parse(event.data);
    for(var comm in command)
    {
      switch(comm) {
        case "text":
            document.getElementById("storage").innerHTML = command["text"];
            reak;
        case "image":
            var fname = command["image"];
            image.src= fname
            processImage(fname);
            reak;	
       }
    }
  };

  function askImage()  {
    socket.send('{ "image": ""}'); 
  }

L'image est chargée directement par le navigateur en assignant la propriété src de l'objet image avec le chemin fourni par le serveur. Avant d'être affichée dans la balise canvas, elle peut recevoir des transformations, comme un ajustement de taille, mais le code n'est pas affiché ici (il est disponible dans l'archive).

Code HTML

<form action="" method="">
  <input type="button" onclick="askImage()" value="Send me an image">
</form>
<div id="inner">
<fieldset>
<div id="storage"></div>
</fieldset>
<canvas id="mycanvas"></canvas>
</div>

Le code source complet est disponible dans l'archive à télécharger...

Pour lancer le script, tapez:

node wsdemo.js

Puis chargez la page wsdemo.html avec l'explorateur de fichier ou la commande CTRL-O d'un navigateur.