介绍

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::Data对象存储客户端接收到的数据, isBinary属性用来判断数据是二进制还是文本,len说明数据长度,bytes指向数据。

void WebSocketTestLayer::onMessage(network::WebSocket* ws, const network::WebSocket::Data& data)
{
    if (!data.isBinary)
    {
        _sendTextTimes++;
        ] = {};
        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内存,并养成良好的习惯:置空指针。

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)
    {
        ] = {};
        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.")
end

local function wsSendTextMessage(strData)
    receiveTextTimes= receiveTextTimes +
    local strInfo= "response text msg: "..strData..", "..receiveTextTimes
    sendTextStatus:setString(strInfo)
end

local function wsSendTextClose(strData)
    print("_wsiSendText websocket instance closed.")
    sendTextStatus = nil
    wsSendText = nil
end

local 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()

【转】【cocos2d-x教程】如何使用WebSocket的更多相关文章

  1. 【Cocos2d入门教程六】Cocos2d-x事件篇之触摸

    Cocos游戏当中产生一个事件时,可以有多个对象在监听该事件,所以有优先级(Priority).优先级越高(Priority值越小),事件响应越靠前. 关系图: 新 事件分发机制:在2.x 版本事件处 ...

  2. Cocos2d-X网络编程(3) Cocos2d中的网络通信协议——WebSocket协议

    WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信.实现浏览器与服务器的即时通讯.即服务器也能主动向客户端发消息. WebSocket代理类和方法: co ...

  3. Spring Boot2 系列教程 (十七) | 整合 WebSocket 实现聊天室

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 昨天那篇介绍了 WebSocket 实现广播,也即服务器端有消息时,将消息发送给所有连接了当前 endpoint 的浏览器.但 ...

  4. 【Cocos2d入门教程四】Cocos2d-x菜单篇

    游戏世界多姿多彩,无论多靓丽的游戏,多耐玩的游戏,在与游戏用户交互上的往往是菜单. 上一章我们已经大概了解了导演.节点.层.精灵.这一章以菜单为主题. 菜单(Menu)包含以下内容: 1.精灵菜单项( ...

  5. 【Cocos2d入门教程三】HelloWorld之一目了然

    什么程序都是从HelloWorld先开始.同样Cocos2d-x我们先从HelloWorld进行下手.下面是HelloWorld的运行完成图: 建立好的Cocos游戏项目中会有两个比较常用接触的文件夹 ...

  6. 【Cocos2d入门教程八】浅析Cocoss2d下的音频引擎及封装音频类

    Cocos2d-x提供了一个音频CocosDenshion引擎,CocosDenshion引擎可以独立于Cocos2d-x单独使用,CocosDenshion引擎本质上封装了OpenAL音频处理库.具 ...

  7. 【Cocos2d入门教程七】三分钟看懂Cocos2d坐标系

    无论是搞2d还是3d开发,最需要搞清楚的就是坐标系,这部分混乱的话就没啥搞头了.所以玩cocos2d,一上来就需要先把各种与坐标有关的东西搞清楚. 1.OpenGL坐标系 Cocos2d-x使用的是O ...

  8. 【Cocos2d入门教程二】Cocos2d-x基础篇

    上一章已经学习了环境的搭建.这一章对基础概念进行掌握.内容大概有: 1.导演 2.场景 3.节点 4.层 4.精灵 1.导演(Director) 导演存在的主要作用: a.环境设定(帧率 初始化ope ...

  9. 【Cocos2d入门教程五】Cocos2d-x动作篇

    动作类(Action)是所有动作的基类,它创建的一个对象代表一个动作.动作作用于Node,包括继承于之下的Layer.Sprite.因此每个动作 都需要由Node对象或者其继承者执行.动作类(Acti ...

  10. iPhone开发与cocos2d 经验谈

    转CSDN jilongliang : 首先,对于一个完全没有mac开发经验,甚至从没摸过苹果系统的开发人员来说,首先就是要熟悉apple的那一套开发框架(含开发环境IDE.开发框架uikit,还有开 ...

随机推荐

  1. 1035 Password (20)

    #include <stdio.h> #include <string.h> struct MyStruct { ]; ]; bool changed; }; int main ...

  2. poj 3518 Corporate Identity 后缀数组->多字符串最长相同连续子串

    题目链接 题意:输入N(2 <= N <= 4000)个长度不超过200的字符串,输出字典序最小的最长公共连续子串; 思路:将所有的字符串中间加上分隔符,注:分隔符只需要和输入的字符不同, ...

  3. Linux命令执行顺序— ||和&&和;

    command1 && command2: &&左边的command1执行成功(返回0表示成功)后,&&右边的command2才能被执行. comman ...

  4. Jsonp 跨域请求实例

    关于jsonp的一个实例,其实自己也不是很了解,今天下午稍微研究了一下: 简单来说,jsonp就是为了两个不同网站之间数据传递而产生的,主要用于js脚本,因为浏览器本身是禁止跨域访问的: 本机实例: ...

  5. c# 模拟表单提交,post form 上传文件、大数据内容

    表单提交协议规定:要先将 HTTP 要求的 Content-Type 设为 multipart/form-data,而且要设定一个 boundary 参数,这个参数是由应用程序自行产生,它会用来识别每 ...

  6. js中arguments的作用

    在javascript函数体内,标识符arguments具有特殊含义.它是调用对象的一个特殊属性,用来引用Arguments对象. Arugments对象就像数组,注意这里只是像并不是哈. javas ...

  7. random note

    今天才慢慢意识到,什么才是学习,(以思考解决问题为驱动),埋头刷分只是方法,不是目的和原动力. 既然准备读研,就要慢慢去了解研究生的生活学习方式是什么样的,涉及到哪些方面. 读研之前要选好方向,但是现 ...

  8. 用于软件包管理的21个Linux YUM命令

    FROM:http://os.51cto.com/art/201309/411895.htm YUM(Yellowdog Updater Modified)是一款开源命令行及图形化软件包管理工具,面向 ...

  9. 高性能图文混排框架,构架顺滑的iOS应用-b

    About GallopGallop是一个功能强大.性能优秀的图文混排框架. Features主要用于解决以下需求: 滚动列表的性能优化.Gallop使用异步绘制.视图层级合并.观察mainRunlo ...

  10. Nhibernate 多对多级联更新

    问题是这样的,有两个表:文章(Article)和分类(Lable),这两者之间的关系是多对多关联,如果你用Nhibernate来保存数据的话非常的好操作,新建Article,然后把Lable值赋值给A ...