我想发送这个示例数组
[{
id: 1,
name: "test",
position: [1234,850], //random position on the map
points: 100 //example points
}];
以我的websocket服务器作为二进制数据。在服务器端,我希望将二进制数据解码回数组,进行更改并将二进制数据发送回客户端。最后在客户端如何将二进制数据解码回数组?
示例屏幕截图我的意思是:
这是我的实际代码:
var connection = new WebSocket('wss://my_website.eu:1234');
connection.binaryType = "ArrayBuffer";
connection.onmessage = function (event) {
// console.log(event);
if (event.data instanceof window["ArrayBuffer"]) {
var data3 = JSON.parse(String.fromCharCode.apply(null, new Uint16Array(event.data)));
console.log(data3);
} else {
console.log(event.data); // Blob {size: 0, type: ""}
}
};
$("body").mousemove(function( event ) {
var data = {
name: "lol",
pos: [event.pageX, event.pageY]
};
//convert to binary frame
var data2 = new Uint16Array(data);
console.log(data2); // []
//try to convert back to array
var data3 = String.fromCharCode.apply(null, new Uint16Array(data2));
console.log(data3); // empty
connection.send(data2); // Binary Frame (Opcode 2, mask) | length: 0
});
服务器端代码:
connection.on('message', function(message) {
for (var i = players.length - 1; i >= 0; i--) {
players[i].connection.send(message.binaryData);
}
});
我现在可以将消息作为二进制帧发送到websocket服务器。 I found functions将字符串转换为二进制类型并将其发送到ws服务器。
现在我有问题了。此功能(如下)不在服务器端工作。示例代码:
var data = {
name: "value"
};
connection.send(JSON.stringify(data));
此代码运行良好。现在,当我尝试作为数组缓冲区发送时:
var data = {
name: "value"
};
connection.send(StringToArrayBuffer(JSON.stringify(data)));
输出不是二进制帧,只是字符串“[object ArrayBuffer]”:
我也尝试过:
connection.send(JSON.stringify(data), {binary: true, mask: false});
但是这个发送消息是普通字符串,而不是二进制帧。
那么,如何将二进制帧从websocket服务器发送到客户端?当我发回收到的二进制消息:
connection.on('message', function(message) {
for (var i = players.length - 1; i >= 0; i--) {
playerConnection[i].send(message.binaryData);
}
}
只有这样才有效。
答案 0 :(得分:9)
首先,浏览器以不同于NodeJS的方式处理二进制数据。在浏览器中,二进制文件可以被视为ArrayBuffer
或Buffer
,但在NodeJS中,它被视为ArrayBuffer
无法理解data
。我不太深入,但你需要在浏览器和nodeJS之间区别对待BinaryType
。
在浏览器端使用WebSocket时,数据以字符串或二进制形式传输,如果使用二进制,则必须指定ArrayBuffer
,在这种特殊情况下,我将使用{{1} }。
至于字符串到缓冲区,我建议使用标准的UTF-8,因为有两种编码UTF-16的方法。例如' \ u0024'在UTF-16中,UTF-16BE中存储为00 24,在UTF-16LE中,它存储为24 00.也就是说,如果要使用UTF-16,则应使用TextEncoder和TextDecoder。否则你可以简单地做到这一点
strToAB = str =>
new Uint8Array(str.split('')
.map(c => c.charCodeAt(0))).buffer;
ABToStr = ab =>
new Uint8Array(ab).reduce((p, c) =>
p + String.fromCharCode(c), '');
console.log(ABToStr(strToAB('hello world!')));

对于UTF-16,浏览器代码应类似于:
const ENCODING = 'utf-16le';
var ws = new WebSocket('ws://localhost');
ws.binaryType = 'arraybuffer';
ws.onmessage = event => {
let str = new TextDecoder(ENCODING).decode(event.data),
json = JSON.parse(str);
console.log('received', json);
};
ws.onopen = () => {
let json = { client: 'hi server' },
str = JSON.stringify(json);
console.log('sent',json);
//JSON.toString() returns "[object Object]" which isn't what you want,
//so ws.send(json) will send wrong data.
ws.send(new TextEncoder(ENCODING).encode(str));
}
在服务器端,数据存储为Buffer
,它或多或少地完成本地的所有操作。但是,您需要指定编码,除非它是UTF-8。
const ENCODING = 'utf-16le';
//You may use a different websocket implementation, but the core
//logic reminds as they all build on top of Buffer.
var WebSocketServer = require('websocket').server,
http = require('http'),
//This is only here so webSocketServer can be initialize.
wss = new WebSocketServer({
httpServer: http.createServer()
.listen({ port: 80 })});
wss.on('request', request => {
var connection = request.accept(null, request.origin);
connection.on('message', msg => {
if (msg.type === 'binary') {
//In NodeJS (Buffer), you can use toString(encoding) to get
//the string representation of the buffer.
let str = msg.binaryData.toString(ENCODING);
console.log(`message : ${str}`);
//send data back to browser.
let json = JSON.parse(str);
json.server = 'Go away!';
str = JSON.stringify(json);
//In NodeJS (Buffer), you can create a new Buffer with a
//string+encoding, and the default encoding is UTF-8.
let buf = new Buffer(str, ENCODING);
connection.sendBytes(buf);
}
});
});
答案 1 :(得分:2)
试一试:
发送数据示例:
var data = [{
id: 1,
name: "test",
position: [1234, 850], //random position on the map
points: 100 //example points
}];
var data2 = new Uint16Array(data);
socket.send(data2);
在你的事件onMessage websocket上尝试:
function onMessage(event) {
if (event.data instanceof window["ArrayBuffer"]){
var data3 = JSON.parse(String.fromCharCode.apply(null, new Uint16Array(event.data)));
};
};