_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) { 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.") end
local function wsSendTextMessage(strData) receiveTextTimes= receiveTextTimes + 1 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() 在JSB中使用 详细代码可参考引擎目录下的/samples/Javascript/Shared/tests/ExtensionsTest/NetworkTest/WebSocketTest.js文件。 创建WebSocket对象 脚本接口相对C++要简单很多,没有头文件,创建WebSocket对象使用下面的一行代码搞定。 参数是服务器地址。 this._wsiSendText = new WebSocket("ws://echo.websocket.org"); 设置消息回调函数 JSB中的回调函数是WebSocket实例的属性,使用匿名函数直接赋值给对应属性。可以看出JS语言的特性,让绑定回调函数更加优美。四个回调的含义,参考上面c++的描述。 this._wsiSendText.onopen = function(evt) { self._sendTextStatus.setString("Send Text WS was opened."); };
this._wsiSendText.onmessage = function(evt) { self._sendTextTimes++; var textStr = "response text msg: "+evt.data+", "+self._sendTextTimes; cc.log(textStr);
self._sendTextStatus.setString(textStr); };
this._wsiSendText.onerror = function(evt) { cc.log("sendText Error was fired"); };
this._wsiSendText.onclose = function(evt) { cc.log("_wsiSendText websocket instance closed."); self._wsiSendText = null; }; send消息 发送文本,无需转换,代码如下: this._wsiSendText.send("Hello WebSocket中文, I'm a text message."); 发送二进制,测试代码中,使用_stringConvertToArray函数来转换string为二进制数据,模拟二进制的发送。 new Uint16Array创建一个16位无符号整数值的类型化数组,内容将初始化为0。然后,循环读取字符串的每一个字符的Unicode编码,并存入Uint16Array,最终得到一个二进制对象。 _stringConvertToArray:function (strData) { if (!strData) returnnull;
var arrData = new Uint16Array(strData.length); for (var i = 0; i < strData.length; i++) { arrData[i] = strData.charCodeAt(i); } return arrData; }, send二进制接口和send文本没有区别,区别在于传入的对象,JS内部自己知道对象是文本还是二进制数据,然后做不同的处理。 var buf = "Hello WebSocket中文,\0 I'm\0 a\0 binary\0 message\0."; var binary = this._stringConvertToArray(buf);