我有一个正在运行的节点服务器,在该服务器中,我生成一堆代表画布上颜色的位并将其存储到Redis中。存储位的每四位代表一种4位颜色。 (例如,如果我存储001001101011111,那么我感兴趣的颜色就是0010、0110、1011和1111)。
var byteArr = new ArrayBuffer(360000);
redis_client.set("board", byteArr);
redis_client.setbit("board", 360000, 0);
// There is some garbage at the beginning of the stored value, so zeroing them out.
for(var i = 0; i < 160; i++){
redis_client.setbit("board", i, 0);
}
当客户端连接到服务器时,我从Redis获取此字符串,并通过Websocket发送它:
wss.on('connection', function(ws) {
redis_client.get("board", function (error, result) {
var initial_send = {"initial_send":true, "board":result};
ws.send(JSON.stringify(initial_send));
});
在客户端,我这样看板:
socket.onmessage = function (event) {
var o = JSON.parse(event.data);
board = o["board"];
var clampedBoard = new Uint8ClampedArray(board.length);
for(var i = 0; i < board.length; i++){
clampedBoard = board[i];
}
}
在这一点上,board
的长度为45000,这是因为在Javascript中,最小的TypedArray
构造函数仅允许1个字节单位。因此,因为我的初始ArrayBuffer的大小为360000,所以当我在客户端中收到它时,它的大小为360000/8。
这是我遇到问题的地方。此时,如果我得到clampedBoard[0]
,它应该给我前8位(我关心的前两种颜色),然后我可以执行clampedBoard[0]>>4
和clampedBoard[0]&15
来获得两种颜色,然后我可以
在键为0000、0001等的地图中查找它们。
但这不是正在发生的事情。
这就是我尝试过的,我知道的:
在客户端打印出值:console.log(clampedBoard[0])
在Chrome的控制台上返回[]看起来为空/未定义的字符。
在服务器端,初始化byteArr
并将前160个值清除为0时,我将前8位手动设置为'00111111',这是ASCII字符'?的二进制表示形式。 '。
当在客户端上进行console.logging clampBoard[0]
时,我得到相同的[]空/未定义字符,但是当console.logging board[0]
时,它打印出一个'?'。我不确定为什么会这样。
当尝试通过执行clampedBoard[0]>>4
在我的颜色映射中查找时,它始终默认为字典中表示0的键,即使它应该是0011。
如果我能提供更多信息,请告诉我。
答案 0 :(得分:0)
首先,您可以执行以下操作:
board = o["board"];
var clampedBoard = new Uint8ClampedArray(board);
因此您不需要值初始化循环。
此外,按照将其传递给对象的方式,“字符串化”会将其转换为字符串而不是数组。为了获得一个数组,您需要从ArrayBuffer中创建一个Node.js的Buffer,然后将其转换为本地数组,如下所示:
var view = Buffer.from(result);
var initial_send = {"initial_send":true, "board":[...view]};