背景:多用户应用程序(node.js)- 1位画家,n个客户端
画布尺寸:650x400像素(= 260,000像素)
为了经常更新画布(我考虑每秒10次),我需要将数据大小尽可能地保持小,特别是在考虑上传速率时。
toDataURL()
方法返回一个base64字符串,这很好,但它包含我甚至不需要的大量数据(每像素23位)。 它的长度为8,088(不包括前面的MIME信息),假设JavaScript字符串具有8位编码,则每秒将传输8.1千字节的数据,每秒10次。
我的下一个尝试是使用JS对象来执行不同上下文操作,例如moveTo(x,y)
或lineTo(x,y)
,将它们发送到服务器并通过时间戳接收数据的客户端进行增量更新。 然而,这比base64字符串更低效。
{
"timestamp": 0,
"what": {
"name": LINE_TO,
"args": {"x": x, "y": y}
}
}
由于在轻扫画笔时已经有近300个lineTo命令,因此它的运行不够流畅和准确。有时候会出现移动的一部分缺失(将一条线变成直线),有时候脚本客户端甚至无法识别事件,因为它似乎被已经触发的大量事件“压垮”了。
因此,我最终使用了带有8.1 KB的base64字符串。我不想过多地担心这个问题——即使使用增量更新异步完成,实际服务器上也会有很大的延迟,更不用说偶尔的带宽超限了。
我只使用#000和#FFF两种颜色,所以我考虑使用仅带有增量更新的1位数据结构。这基本上就足够了,我不介意任何“颜色”精度损失(毕竟它是黑色的)。
由于大部分画布都是白色的,您可以考虑使用额外的哈夫曼游程编码来进一步减小大小。例如,一个大小为50x2像素且在(26,2)处有一个单独的黑色像素的画布将返回以下字符串:
75W1B74W
(50个白色像素加上25个白色像素,然后是1个黑色像素,然后是24个白色像素)。如果画布由像这样的1位字符串组成,甚至可以帮助减小大小:
00000000000000000000000000000000000000000000000000
00000000000000000000000001000000000000000000000000
那已经非常有帮助了。
我的第一个问题是:如何编写一种算法来有效地获取这些数据?
第二个问题是:我如何将纯二进制画布数据通过节点服务器传递给客户端?我该如何发送1位数据结构到服务器?我需要将位转换为十六进制(或更多)数字并重新解析吗?
是否可以使用这个作为数据结构?
提前致谢,
Harti
{ "timestamp": 0, "what": { "name": LINE_TO, "args": {"x": x, "y": y} } }
然而,用一个大约60x40像素的单个画笔线,你已经有超过300个这样的命令了。 不过用简单(更短)的字符串代替对象的想法听起来也很不错。用对象的方法对我来说没有很流畅(在本地主机上)。Base64 字符串可以流畅运行,但我担心这只适用于局域网节点服务器。 - Harti