通过WebSocket 传送Binary 数据:ArrayBuffe
这篇算是延续之前的《HTML5 WebSocket Client使用详解》和《C++ WebSocket函数库:WebSocket++》这两篇文章,来整理一下,除了传递文字数据外,要怎么通过WebSocket来传递Binary数据。而client端基本上还是一般的JavaScript、Server端也就还是WebSocket++了~
基本上,WebSocket在JavaScript这端,除了纯文字(DOMString),在二进位数据的方面,还支援Blob和ArrayBuffer两种类型的数据。Blob基本上是一种没有特定原生JavaSctipt型别的RAW Data,里面可以塞各式各样的东西(参考);而ArrayBuffer则是固定宽度的数组数据,不过由于本身没有记录内容的型别,所以必须通过ArrayBufferView的物件、来指定内容的型别做存取(参考)。
而Heresy这边,基本上就是使用ArrayBuffer来做数据的传递C++里面的数组。
JavaScript Client
基本上,要在JavaScript里面接收WebSocket传来的ArrayBuffer数据,在程序架构上,并不需要做太大的修改;要注意的是,由于WebSocket支援的Binary数据形式有Blob和ArrayBuffer两种,所以必须要手动指定要用哪种类型的数据。
而指定的方法,基本上就是在建立出WebSocket的物件后,去指定他的binaryType的值:
- var wWebsocket = new WebSocket(sUri);
- wWebsocket.binaryType = "arraybuffer" ;
他的值只有「arraybuffer」和「blob」两种,在设置之后,就会以指定的形式,来处理收到的binary数据。
而在数据的处理方面,一样是要在onmessage这个事件的callback function里面做处理。基本上的概念,就是先就是要先通过instanceof来确认收到的数据是否为需要的型别,然后再转换成对应的ArrayBufferView物件来做使用。像如果接收到的数据是64bit的浮点数(double),程序的写法大致就会像下面这样:
- wWebsocket.onmessage = function (evt) {
- if ( evt.data
- { var aDataArray = new Float64Array( evt.data );
- }
- }
- };
其中,Float64Array就是一种ArrayBufferView的型别;当把接收到的数据(evt.data
而除了Float64Array这个型别外,还有其他几种、各自对应到不同类型数据的ArrayBufferView型别,基本上如下表(参考):
|
型别
|
大小
|
对应到C 的型别
|
|---|---|---|
|
Int8Array
|
1
|
char
|
|
Uint8Array
|
1
|
unsigned char
|
|
Int16Array
|
2
|
short
|
|
Uint16Array
|
2
|
unsigned short
|
|
Int32Array
|
4
|
int
|
|
Uint32Array
|
4
|
unsigned int
|
|
Float32Array
|
4
|
float
|
|
Float64Array
|
8
|
double
|
至于要转换成哪一种型别,就是要自己和server端先做好沟通,搞清楚接下来要传送的是哪一种类型的数据,才能做进一步的处理了。(这时候真的觉得asynchronous io很讨厌…)
WebSocket++ Server
上面是client 端的JavaScript 程序,而接下来则是WebSocket++ 的Server 端程序。
基本上,WebSocket++的endpoint所提供的send()函数,本身就有提供了对应的介面,可以用来传递void*、任何型别的数组,算是相当方便的。不过由于考虑到client端只有提供基础型别的ArrayBufferView型别来做对应,所以这边还是建议只能来传C内建的基础型别数据的数组就好了。
而以要传递一个double 的数组的话,大致上会是像下面这样子:
- double aData[10];
- for ( int i = 0; i < 10; ++ i )
- aData[i] = i; rServer .send( hdl , aData, 10 * sizeof ( double ),websocketpp::frame::opcode :: BINARY );
基本上,sned()所需要的第一个参数,还是一样是connection_hdl,用来决定要传 ??给谁。而第二个参数,而是接受const void*,用来接受任意型别的数组;第三个参数,则是要告诉他这个数组有多大,基本上就是数组程度、乘上每一项的大小了。最后,则是要告诉WebSocket++是要使二进位的数据,所以指定opcode是BINARY。
而如果要传递其他型别的数组,也只要用同样的方法,就可以了~
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
