Cocos2d WebSocket協議 簡單例子

 

WebSocket protocol 是HTML5一種新的協議。它實現了瀏覽器與服務器全雙工通信。實現瀏覽器與服務器的即時通訊。即服務器也能主動向客戶端發消息。

 

WebSocket代理類和方法:

cocos2d同樣對websocket進行了封裝。WebSocket和WebSocket::Delegate
1:WebSocket:
   WebSocket類提供了跟websocket相關操作的方法。它的作用包括:
   1、創建socket對象
   2、向服務器發送數據,可以是文本數據,也可以是二進制數據
   3、判斷鏈接狀態  
       enum class ErrorCode
       {
               TIME_OUT,
               CONNECTION_FAILURE,
               UNKNOWN,
       };
   等等。
 
2:WebSocket::Delegate:
   類似Socket。WebSocket::Delegate提供了4個純虛函數,在使用websocket時,需要先繼承Delegate類和實現這4個虛函數。

 

創建WebSocket對象併發送文本數據:

創建對象:
   cocos2d::network::WebSocket* wsSendText = new network::WebSocket()
初始化請求地址:
   wsSendText ->init(*this, "ws://echo.websocket.org")。
發送數據:
   wsSendText ->send("Hello WebSocket, I'm a text message.");

 

接收數據:

當服務器向客戶端發送數據,客戶端會調用onMessage方法接收返回的數據。
數據使用WebSocket::Data封裝。它是cocos2d定義的一個結構體。結果如下:
struct Data
    {
        Data():bytes(nullptr), len(0), issued(0), isBinary(false){}
        char* bytes;
        ssize_t len, issued;
        bool isBinary;
    };
它包含四個字段:bytes存放數據,len存放數據的長度,isBinary用來標識bytes中存放的數據是文本數據還是二進制數據。
使用Data結構體得到數據後,就可以使用這些數據了。


代碼實操:

頭文件:

#ifndef __TestWebSocketScene_SCENE_H__
#define __TestWebSocketScene_SCENE_H__

#include "cocos2d.h"
#include "network\WebSocket.h"
USING_NS_CC;

using namespace cocos2d::network;
class TestWebSocket : public cocos2d::Layer
	,WebSocket::Delegate
{
	public:
		static cocos2d::Scene* createScene();
		virtual bool init();
		CREATE_FUNC(TestWebSocket);
   
		virtual void onOpen(WebSocket *ws);
		virtual void onMessage(WebSocket *ws,const WebSocket::Data &data);
		virtual void onClose(WebSocket *ws);
		virtual void onError(WebSocket *ws,const WebSocket::ErrorCode& error);

	private:
		// 創建對象
		WebSocket *wsText;
};

#endif // __TestWebSocketScene_SCENE_H__

源文件:

#include "TestWebSocketScene.h"

Scene* TestWebSocket::createScene()
{
    auto scene = Scene::create();
    auto layer = TestWebSocket::create();
    scene->addChild(layer);
    return scene;
}

bool TestWebSocket::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
	Size size = Director::getInstance()->getWinSize();
	wsText = nullptr;

	auto menu = Menu::create();
	menu->setPosition(Vec2::ZERO);
	addChild(menu);

	auto lblSendText = Label::create("init websocket","Arial",22);
	auto menuSendText = MenuItemLabel::create(lblSendText,[=](Ref *sender){
		wsText = new WebSocket();
		// 初始化請求地址
		if( !wsText->init(*this,"ws://echo.websocket.org")){
			// 初始化失敗則刪除
			CC_SAFE_DELETE(wsText);
		};
	});
	menuSendText->setPosition(size/2);
	menu->addChild(menuSendText);

	auto lblSend = Label::create("send","Arial",22);
	auto menuSend = MenuItemLabel::create(lblSend,[=](Ref *sender){
		if (wsText!=nullptr)
		{
			// 發送數據
			wsText->send("hello websocket.");
		}
	});
	menuSend->setPosition(size.width/2,size.height/2-50);
	menu->addChild(menuSend);

	auto lblSendBinary = Label::create("sent Binary","Arial",22);
	auto menuSendBinary = MenuItemLabel::create(lblSendBinary,[=](Ref *sender){
		if (wsText!=nullptr)
		{
			char buffer[] = "hello \0 binary";
			wsText->send((unsigned char *)buffer,sizeof(buffer));
		}
	});
	menuSendBinary->setPosition(size.width/2,size.height/2-100);
	menu->addChild(menuSendBinary);

    return true;
}

void TestWebSocket::onOpen(WebSocket *ws){
	log("webSocket (%p) open",ws);
	// webSocket沒有http那種tag用於區分不同的請求
	// webSocket使用如下方法區分不同請求
	if (ws==wsText)
	{
		log("WebSocket send Text open");
	}
	
}

void TestWebSocket::onMessage(WebSocket *ws,const WebSocket::Data &data){
	log("webSocket (%p) receive message",ws);
	if (!data.isBinary)
	{//文本數據
		log("received message is :%s",data.bytes);
	}else//二進制數據的處理
	{
		std::string result;
		for (int i = 0; i < data.len; i++)
		{
			if (data.bytes[i]!='\0')
			{
				result +=data.bytes[i];
			}else
			{
				result += "\'\\0\'";
			}
		}
		log("received binary data is: %s",result.c_str());
	}
}

void TestWebSocket::onClose(WebSocket *ws){
	log("webSocket (%p) close",ws);
	if (ws==wsText)
	{
		log("WebSocket send Text close");
	}
}

void TestWebSocket::onError(WebSocket *ws,const WebSocket::ErrorCode &error){
	log("WebSocket (%p) error",ws);
	if (ws==wsText)
	{
		log("WebSocket send Text error");
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章