透過 WebSocket 傳送 Binary 資料:ArrayBuffer(補充)

| | 0 Comments| 09:11
Categories:

這篇基本上是針對前一篇《透過 WebSocket 傳送 Binary 資料:ArrayBuffer》作一些補充。
在《透過 WebSocket 傳送 Binary 資料:ArrayBuffer》一文中,Heresy 主要是在針對由 WebSocket 的 C Server,傳遞 binary 資料到網頁的 JavaScript Client 來做說明。不過相對的,Heresy 倒是忘了要去弄反方向、也就是由 JavaScript 送 binary 資料到 Server 的部分了;而這一篇,就是簡短地說明一下,反過來由 JavaScript 送到 WebSocket Server 要怎麼做。


JavaScript Client

要從 JavaScript 透過傳送 ArrayBuffer 的資料給遠端的 Server,首先要準備一個 ArrayBufferView 的陣列,來存放所要傳遞的資料。而由於他有提供幾種不同的建構子,所以也可以慘用不同的方法,來建立要傳遞的資料;這邊 Heresy 是以 32bit 的浮點數、也就是 Float32Array 來作範例。

下面就是簡單的範例程式:

var aDataArray = new Float32Array(9);
for (var i = 0; i < 9; i)
aDataArray[i] = i;
wWebSocket.send(aDataArray);

在上面的範例程式裡面,主要就是先建立一個長度為 9 的 Float32Array、並依序把每一項設定對應的值,然後再透過 WebSocket 物件(wWebSocket)的 send() 這個函式,把整個陣列送出去,這樣就可以了~

使用上在準備好資料後,基本上就和傳送文字訊息的方法相同,相當地方便(詳細請參考《HTML5 WebSocket Client》);而如果要換成其他類型的 ArrayBufferView 來做傳輸,也可以相當簡單地做修改。


WebSocket Server

在 Server 端的部分,整個流程還是和之前《C WebSocket 函式庫:WebSocket 》的說明相同,而不管接到的資料是字串或是 binary 資料,基本上都是會觸發到我們設定好的 on_message() 這個 callback function。

所以,當 on_message() 被觸發後,第一件要做的事情,應該是要透過 websocketpp::server<>::message_ptr 提供的 get_opcode(),來確認接到的資料是文字還是 binary,然後再各自做處理。不過,由於取得資料的函式 get_payload() 回傳的資料,基本上一定會是 const string& 的形式,所以這邊會需要根據收到的內容,來做強制性的轉換。

這邊的程式,大概可以寫成下面這個樣子:

void on_message(websocketpp::connection_hdl hdl, server::message_ptr msg)
{
if( msg->get_opcode() == websocketpp::frame::opcode::BINARY )
{
const std::string& sInput = msg->get_payload();

const float* pDataArray = reinterpret_cast<const float*>( sInput.data() );
unsigned int uLength = sInput.length() / sizeof(float);

for( unsigned int i = 0; i < uLength; i )
cout << pDataArray[i] << endl;
}
}

上面的範例裡面,第一個條件判斷,就是用來確認接收到的訊息(msg)是否為 binary 的資料的;而如果是 binary 資料的話,接下來還是一樣,先透過 get_payload()、以 C STL 字串的形式來取得他的資料(sInput)。

接下來呢,則是透過 stringdata() 這個函式,來取得字串的內容的指標(基本上就是 C 的字元陣列、const char*參考),並且透過  reinterpet_cast參考)、來強制把得到的指標,從 const char* 轉換成 const float*,也就是最後得到的 pDataArray

而資料長度的部分呢,基本上一樣是從本來的字串來做計算。透過 std::stringlength() 函式,可以知道這筆資料有幾位元組(他是回傳字元數,而一個字元就是 1 byte);而接下來,只要針對轉換後的型別來換算,就可以算出來轉換後的陣列有多大了。以這個例子來說,因為是要把資料轉換成 float 的形式,所以只要拿 length() 除以 sizeof(float)(原則上會是 4),就可以得到 pDataArray 的長度了。

而之後,就可以按照一般 C 陣列的方法,來針對轉換出來的資料,也就是長度為 uLengthfloat 陣列、pDataArray 進行資料的讀取了~


這篇就先這樣了,接下來,就是準備來傳整張影像試試看了。

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *