问题
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()
回答1:
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.
来源:https://stackoverflow.com/questions/32595130/javascript-html5-canvas-display-from-python-websocket-server