Cocos2d-X网络编程(3) 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");
	}
}

 

 

posted @ 2018-09-01 00:38  穆玄琅  阅读(1153)  评论(0编辑  收藏  举报