TestWebSocketScene.h文件:
#ifndef __TestWebSocketScene_SCENE_H__
#define __TestWebSocketScene_SCENE_H__
#include "cocos2d.h"
#include "network\WebSocket.h"
USING_NS_CC;
using namespace cocos2d::network;
//继承WebSocket::Delegate,实现四个虚拟方法
class TestWebSocket : public cocos2d::Layer,WebSocket::Delegate
{
public:
// there's no 'id' in cpp,so we recommend returning the class instance pointer
static cocos2d::Scene* createScene();
// Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'id' in cocos2d-iphone
virtual bool init();
//连接时调用
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);
// implement the "static create()" method manually
CREATE_FUNC(TestWebSocket);
private:
WebSocket *wsText;
};
#endif // __TestWebSocketScene_SCENE_H__
TestWebSocketScene.cpp文件:
#include "TestWebSocketScene.h"
Scene* TestWebSocket::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = TestWebSocket::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool TestWebSocket::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
Size size = Director::getInstance()->getWinSize();
wsText = nullptr;//初始化为空指针
auto menu = Menu::create();
menu->setPosition(Vec2::ZERO);
addChild(menu);
//1.初始化websocket
auto lblSendText = Label::create("init websocket text","Arial",22);
auto menuSendText = MenuItemLabel::create(lblSendText,[=](Ref *sender){
wsText = new WebSocket();
//初始化请求地址
if( !wsText->init(*this,"ws://echo.websocket.org")){
CC_SAFE_DELETE(wsText);//初始化失败:delete掉该对象,置空。
};
});
menuSendText->setPosition(size/2);
menu->addChild(menuSendText);
//2.发送text数据
auto lblSend = Label::create("sent text",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);
//3.发送Binary数据
auto lblSendBinary = Label::create("sent Binary",22);
auto menuSendBinary = MenuItemLabel::create(lblSendBinary,[=](Ref *sender){
if (wsText!=nullptr)
{
char buffer[] = "hello \0 binary";
wsText->send((unsigned char *)buffer,sizeof(buffer));//需要的是 unsigned char*要强制类型转换
}
});
menuSendBinary->setPosition(size.width/2,size.height/2-100);
menu->addChild(menuSendBinary);
return true;
}
void TestWebSocket::onOpen(WebSocket *ws){
log("webSocket (%p) open",ws);
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')//不等于0
{
result +=data.bytes[i];
}else
{
result += "\'\\0\'";//转义字符 \' --> ' \\ --> \ 结果'\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");
}
}
知识点: 返回的数据使用WebSocket::Data封装,它是cocos2d定义的一个结构体 struct Data { Data():bytes(nullptr),len(0),issued(0),isBinary(false){} char* bytes; //存放的数据 ssize_t len,issued;//数据的长度 bool isBinary; //标识文本时文本数据还是二进制数据 };