javascript HTML5 canvas display from python websocket server
Question: I created a websocket server that uses ZeroMQ4 to talk to a middleware. I also
created a peice of Javascript to display information back from the middleware.

I know the Websocket server works and is able to send to the javascript as i
tested with small string output.

So, I want to send an png image from the websocket server to Javascript, but
the Javascript documentation of canvas is confusing and I haven't found a
solid example good for a newbie with Javascript.

This is the Javascript I have so far it is able to input data in, but does not
display any image.

    
    
    var canvas = document.getElementById('stage');
    var context = canvas.getContext("2d");
    
    function openWS(){
        var websocket = new WebSocket("ws://raptorweb1.no-ip.org:10000");
        websocket.binaryType = "arraybuffer";
        websocket.onmessage = function(evt) { onMessage(evt) };
        websocket.onerror = function(evt) { onError(evt) };
        websocket.onopen = function(evt) { onOpen(evt) };
        function onOpen(evt){
            var luser = document.getElementById("lusername").value;
            var ruser = document.getElementById("rusername").value;
            var pwd = document.getElementById("password").value;
            console.log("Connecting.. ");
            websocket.send("SUB[00100]" + luser);
            websocket.send("MESSAGE[00100]" + ruser + "[11111]" + pwd);
            console.log("Connected.");
        }
    
        function onMessage(evt) {
            console.log("received: " + evt.data);
            drawImageBinary(evt.data);
        }
    
        function onError(evt) {
            console.log(evt.data);
        }
    
    
        function drawImageBinary(blob) {
            var bytes = new Uint8Array(blob);
            // console.log('drawImageBinary (bytes.length): ' + bytes.length);
            var imageData = context.createImageData(canvas.width, canvas.height);
            for (var i=8; i<imageData.data.length; i++) {
                imageData.data[i] = bytes[i];
            }
            context.putImageData(imageData, 0, 0);
            var img = document.createElement('img');
            //img.height = canvas.height;
            //img.width = canvas.width;
            img.src = canvas.toDataURL();
        }
    }
    

this is the websocket server:

    
    
    clients = []
    from SimpleWebSocketServer import WebSocket, SimpleWebSocketServer,     SimpleSSLWebSocketServer
    import zmq
    import zmq.auth
    from zmq.auth.thread import ThreadAuthenticator
    import sys
    import os
    import random
    import pygame
    from pygame.locals import *
    import base64
    import string
    from threading import Thread
    def id_generator(size=10, chars=string.ascii_uppercase + string.digits):
        return ''.join(random.choice(chars) for _ in range(size))
    class SimpleChat(WebSocket):
        def initZMQ(self):
            file = sys.argv[0]
            base_dir = os.path.dirname(file)
            keys_dir = os.path.join(base_dir, 'certificates')
            public_keys_dir = os.path.join(base_dir, 'public_keys')
            secret_keys_dir = os.path.join(base_dir, 'private_keys')
            self.context = zmq.Context()
            self.socket = self.context.socket(zmq.DEALER)
            client_secret_file = os.path.join(secret_keys_dir, "client.key_secret")
            client_public, client_secret = zmq.auth.load_certificate(client_secret_file)
            self.socket.curve_publickey = client_public
            self.socket.curve_secretkey = client_secret
            server_public_file = os.path.join(public_keys_dir, "server.key")
            server_public, _ = zmq.auth.load_certificate(server_public_file)
            self.socket.curve_serverkey = server_public
            self.width = "0"
            self.height = "0"
        def ondata(self):
            while True:
                try:
                    data = self.socket.recv()
                    code, self.width = data.split('[55555]')
                    data = self.socket.recv()
                    code, self.height = data.split('[55555]')
                    self.width = int(self.width)
                    self.height = int(self.height)
                    self.width = float(self.width /1.5)
                    self.height = float(self.height /1.5)
                    print (self.width, self.height)
                    data = self.socket.recv()   
                    image = pygame.image.frombuffer(data, (int(self.width),int(self.height)),"RGB")
                    randname = id_generator()
                    pygame.image.save(image,randname+".png")
                    out = open(randname+".png","rb").read()
                    self.sendMessage(out)
                    print("data sent")
                    os.remove(randname+".png")
                except Exception as e:
                    print (e)
        def handleMessage(self):
           try:
               message = str(self.data) 
               protocode, msg = message.split("[00100]")
               if protocode == ("SUB"):
                   print("SUB")
                   self.socket.setsockopt(zmq.IDENTITY, str(msg))
                   self.socket.connect("tcp://127.0.0.1:9001")
                   Thread(target=self.ondata).start()
               elif protocode == ("MESSAGE"):
                   print("MESSAGE")
                   msg = str(msg)
                   ident, mdata = msg.split("[11111]")
                   msg = ('%sSPLIT%s' % (ident, mdata))
                   self.socket.send(str(msg))
               else:
                   raise Exception
           except Exception as e:
               print (e)
    
        def handleConnected(self):
           print (self.address, 'connected')
           clients.append(self)
           self.initZMQ()
    
    
        def handleClose(self):
           clients.remove(self)
           print (self.address, 'closed')
           for client in clients:
              client.sendMessage(self.address[0] + u' - disconnected')
    
    server = SimpleWebSocketServer('', 10000, SimpleChat)
    server.serveforever()
    


Answer: I managed to solve this problem.

Turns out that my javascript and my python server were wrong.

this is the function that works for me when processing the message from the
server:

    
    
    function onMessage(evt) {
            var img = new Image();
            img.src = "data:image/png;base64,"+evt.data;
            img.onload = function () {
                context.drawImage(img,0,0);
            }
    }
    

I had to add a base64.b64encode on my server right before I send the picture.

