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

Код сервера и клиента для обмена текстом и изображением между сервером и браузером через WebSocket.

Как правило, WebSocket передает строки символов, даже если некоторые фреймворки кажутся передающими более сложные объекты, они делают это с помощью фоновых преобразований. Для передачи объекта он помещается прямо в кавычки, чтобы сделать его строкой, или используется метод stringify. Оба используются в демо, где используется node.js на стороне сервера и фреймворк WebSocket на стороне сервера, а стандартный объект WebSocket используется на стороне браузера.

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

На сервере устанавливается Node.js, а затем nodejs-websocket:

node npm nodejs-websocket

Это также может быть ws, или socketjs, который также обеспечивает соединение между браузерами или любой другой библиотекой. Socket.io становится трудно установить, я бы не стал придерживаться такого введения, но он может подойти для веб-приложений.

Между клиентом и сервером происходит обмен объектами фигуры:

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

или

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

Другой вариант - обменяться несколько более сложными объектами со свойством «type», как это делает демонстрация Xul.fr, причем тип - «text» или «image».

В любом случае объект преобразуется в строку символов перед передачей, а при получении расшифровывается методом JSON parse.

Код сервера

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)

Как видно в случае изображения, сервер проверяет наличие файла и просто отправляет локальный путь к изображению. Мы увидим в клиентском коде, чего достаточно для браузера.

Путь изображения должен быть относительно пути страницы, а не в локальной файловой системе, иначе браузер Chrome откажется от назначения.

Клиентский код JavaScript

 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.