来自python websocket服务器的javascript HTML5画布显示

Posted

技术标签:

【中文标题】来自python websocket服务器的javascript HTML5画布显示【英文标题】:javascript HTML5 canvas display from python websocket server 【发布时间】:2015-09-15 20:34:07 【问题描述】:

我创建了一个使用 ZeroMQ4 与中间件通信的 websocket 服务器。 我还创建了一段 javascript 来显示从中间件返回的信息。

我知道 Websocket 服务器工作正常,并且能够发送到 javascript,因为我使用小字符串输出进行了测试。

所以,我想将一个 png 图像从 websocket 服务器发送到 Javascript,但是 canvas 的 Javascript 文档令人困惑,我还没有找到一个适合 Javascript 新手的可靠示例。

这是我目前拥有的 Javascript,它能够输入数据,但不显示任何图像。

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

这是 websocket 服务器:

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()

【问题讨论】:

【参考方案1】:

我设法解决了这个问题。

原来我的 javascript 和我的 python 服务器是错误的。

这是处理来自服务器的消息时对我有用的功能:

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

在发送图片之前,我必须在我的服务器上添加一个 base64.b64encode。

【讨论】:

以上是关于来自python websocket服务器的javascript HTML5画布显示的主要内容,如果未能解决你的问题,请参考以下文章

如何在网页上存储来自 websocket 的实时数据?

如何用python解析来自websocket的数据?

Eclipse javax.websocket 导入未解决

带有异步计时器的 Python 异步 websocket 客户端

Java Socket 和 JS WebSocket

websocket握手问题