【轉】【cocos2d-x教程】如何使用WebSocket

來源:互聯網
上載者:User

標籤:style   class   blog   code   java   http   

介紹

WebSocket是HTML5開始提供的一種瀏覽器與伺服器間進行全雙工系統通訊的網路技術。在WebSocket API中,瀏覽器和伺服器只需要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以資料互相傳送。

Cocos2d-x引擎整合libwebsockets,並在libwebsockets的用戶端API基礎上封裝了一層易用的介面,使得引擎在C++, JS, Lua層都能方便的使用WebSocket來進行遊戲網路通訊。

引擎支援最新的WebSocket Version 13。

在C++中使用

詳細代碼可參考引擎目錄下的/samples/Cpp/TestCpp/Classes/ExtensionsTest/NetworkTest/WebSocketTest.cpp檔案。

標頭檔中的準備工作

首先需要include WebSocket的標頭檔。

#include "network/WebSocket.h"

cocos2d::network::WebSocket::Delegate定義了使用WebScocket需要監聽的回調通知介面。使用WebSocket的類,需要public繼承這個Delegate。

class WebSocketTestLayer : public cocos2d::Layer, public cocos2d::network::WebSocket::Delegate

 

並Override下面的4個介面:

virtual void onOpen(cocos2d::network::WebSocket* ws);virtual void onMessage(cocos2d::network::WebSocket* ws, const cocos2d::network::WebSocket::Data& data);virtual void onClose(cocos2d::network::WebSocket* ws);virtual void onError(cocos2d::network::WebSocket* ws, const cocos2d::network::WebSocket::ErrorCode& error);

 

 

後面我們再詳細介紹每個回調介面的含義。

建立WebSocket並初始化

WebSocket.org 提供了一個專門用來測試WebSocket的伺服器"ws://echo.websocket.org"。 測試代碼以連結這個伺服器為例,展示如何在Cocos2d-x中使用WebSocket。

建立一個WebSocket:

cocos2d::network::WebSocket* _wsiSendText = new network::WebSocket();

 

init第一個參數是delegate,設定為this,第二個參數是伺服器位址。 URL中的"ws://"標識是WebSocket協議,加密的WebSocket為"wss://".

_wsiSendText->init(*this, "ws://echo.websocket.org")

 

WebSocket訊息監聽

在調用send發送訊息之前,先來看下4個訊息回調。

onOpen

init會觸發WebSocket連結的伺服器,如果成功,WebSocket就會調用onOpen,告訴調用者,用戶端到伺服器的通訊鏈路已經成功建立,可以收發訊息了。

void WebSocketTestLayer::onOpen(network::WebSocket* ws){    if (ws == _wsiSendText)    {        _sendTextStatus->setString("Send Text WS was opened.");    }}

onMessage

network::WebSocket::DataObject Storage Service用戶端接收到的資料, isBinary屬性用來判斷資料是二進位還是文本,len說明資料長度,bytes指向資料。

void WebSocketTestLayer::onMessage(network::WebSocket* ws, const network::WebSocket::Data& data){    if (!data.isBinary)    {        _sendTextTimes++;        char times[100] = {0};        sprintf(times, "%d", _sendTextTimes);        std::string textStr = std::string("response text msg: ")+data.bytes+", "+times;        log("%s", textStr.c_str());        _sendTextStatus->setString(textStr.c_str());    }}

onClose

不管是伺服器主動還是被動關閉了WebSocket,用戶端將收到這個請求後,需要釋放WebSocket記憶體,並養成良好的習慣:置null 指標。

void WebSocketTestLayer::onClose(network::WebSocket* ws){    if (ws == _wsiSendText)    {        _wsiSendText = NULL;    }    CC_SAFE_DELETE(ws);}

onError

用戶端發送的請求,如果發生錯誤,就會收到onError訊息,遊戲針對不同的錯誤碼,做出相應的處理。

void WebSocketTestLayer::onError(network::WebSocket* ws, const network::WebSocket::ErrorCode& error){    log("Error was fired, error code: %d", error);    if (ws == _wsiSendText)    {        char buf[100] = {0};        sprintf(buf, "an error was fired, code: %d", error);        _sendTextStatus->setString(buf);    }}

send訊息到伺服器

在init之後,我們就可以調用send介面,往伺服器發送資料請求。send有文本和二進位兩中模式。

發送文本

_wsiSendText->send("Hello WebSocket, I‘m a text message.");

 

發送位元據(多了一個len參數)

_wsiSendBinary->send((unsigned char*)buf, sizeof(buf));

 

主動關閉WebSocket

這是讓整個流程變得完整的關鍵步驟, 當某個WebSocket的通訊不再使用的時候,我們必須手動關閉這個WebSocket與伺服器的串連。close會觸發onClose訊息,而後onClose裡面,我們釋放記憶體。

_wsiSendText->close();

 

在Lua中使用

詳細代碼可參考引擎目錄下的/samples/Lua/TestLua/Resources/luaScript/ExtensionTest/WebProxyTest.lua檔案。

建立WebSocket對象

指令碼介面相對C++要簡單很多,沒有標頭檔,建立WebSocket對象使用下面的一行代碼搞定。 參數是伺服器位址。

wsSendText = WebSocket:create("ws://echo.websocket.org")

 

定義並註冊訊息回呼函數

回呼函數是普通的Lua function,4個訊息回調和c++的用途一致,參考上面的說明。

local function wsSendTextOpen(strData)    sendTextStatus:setString("Send Text WS was opened.")endlocal function wsSendTextMessage(strData)    receiveTextTimes= receiveTextTimes + 1    local strInfo= "response text msg: "..strData..", "..receiveTextTimes    sendTextStatus:setString(strInfo)endlocal function wsSendTextClose(strData)    print("_wsiSendText websocket instance closed.")    sendTextStatus = nil    wsSendText = nilendlocal function wsSendTextError(strData)    print("sendText Error was fired")end

 

Lua的訊息註冊不同於C++的繼承 & Override,有單獨的介面registerScriptHandler。 registerScriptHandler第一個參數是回呼函數名,第二個參數是回調類型。 每一個WebSocket執行個體都需要綁定一次。

if nil ~= wsSendText then    wsSendText:registerScriptHandler(wsSendTextOpen,cc.WEBSOCKET_OPEN)    wsSendText:registerScriptHandler(wsSendTextMessage,cc.WEBSOCKET_MESSAGE)    wsSendText:registerScriptHandler(wsSendTextClose,cc.WEBSOCKET_CLOSE)    wsSendText:registerScriptHandler(wsSendTextError,cc.WEBSOCKET_ERROR)end

send訊息

Lua中發送不區分文本或二進位模式,均使用下面的介面。

wsSendText:sendString("Hello WebSocket中文, I‘m a text message.")

 

主動關閉WebSocket

當某個WebSocket的通訊不再使用的時候,我們必須手動關閉這個WebSocket與伺服器的串連,以釋放伺服器和用戶端的資源。close會觸發cc.WEBSOCKET_CLOSE訊息。

wsSendText:close()

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.