quick-cocos2d-x 学习系列之十二 关于websocket
quick-cocos2d-x 学习系列之十二 关于websocket 1.概念百度百科:WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。 在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。 在JavaEE7中也实现了WebSocket协议。 实现了websocket的浏览器:
所以这个websocket还是比较靠谱的协议。那么在LUA中如何使用呢? 我们还是以DEMO为引子。 2.Websocket类创建一个websocket类如下: local WebSockets = class("WebSockets") WebSockets.TEXT_MESSAGE = 0 WebSockets.BINARY_MESSAGE = 1 WebSockets.BINARY_ARRAY_MESSAGE = 2 WebSockets.OPEN_EVENT = "open" WebSockets.MESSAGE_EVENT = "message" WebSockets.CLOSE_EVENT = "close" WebSockets.ERROR_EVENT = "error" function WebSockets:ctor(url) cc(self):addComponent("components.behavior.EventProtocol"):exportMethods() self.socket = cc.WebSocket:create(url) if self.socket then self.socket:registerScriptHandler(handler(self,self.onOpen_),cc.WEBSOCKET_OPEN) self.socket:registerScriptHandler(handler(self,self.onMessage_),cc.WEBSOCKET_MESSAGE) self.socket:registerScriptHandler(handler(self,self.onClose_),cc.WEBSOCKET_CLOSE) self.socket:registerScriptHandler(handler(self,self.onError_),cc.WEBSOCKET_ERROR) end end function WebSockets:isReady() return self.socket and self.socket:getReadyState() == cc.WEBSOCKET_STATE_OPEN end function WebSockets:send(data, messageType) if not self:isReady() then printError("WebSockets:send() - socket is't ready") return false end messageType = checkint(messageType) self.messageType = messageType if messageType == WebSockets.TEXT_MESSAGE then self.socket:sendString(tostring(data)) elseif messageType == WebSockets.BINARY_ARRAY_MESSAGE then data = checktable(data) self.socket:sendString(data,table.nums(data)) else self.socket:sendString(tostring(data)) end return true end function WebSockets:close() if self.socket then self.socket:close() self.socket = nil end self:removeAllEventListeners() end function WebSockets:onOpen_() self:dispatchEvent({name = WebSockets.OPEN_EVENT}) end function WebSockets:onMessage_(message) local params = { name = WebSockets.MESSAGE_EVENT, message = message, messageType = self.messageType } self:dispatchEvent(params) end function WebSockets:onClose_() self:dispatchEvent({name = WebSockets.CLOSE_EVENT}) self:close() end function WebSockets:onError_(error) self:dispatchEvent({name = WebSockets.ERROR_EVENT,error = error}) end return WebSockets 3.MainScene调用该类的场景MainScene,如下。 local WebSockets = require("WebSockets") local MainScene = class("MainScene",function() return display.newScene("MainScene") end) local function bin2hex(binary) local t = {} for i = 1,string.len(binary) do t[#t + 1] = string.format("0x%02x",string.byte(binary, i)) end return table.concat(t," ") end function MainScene:ctor() local connectLabel = cc.ui.UIPushButton.new() :setButtonLabel(cc.ui.UILabel.new({text= "connect",size = 32})) :onButtonClicked(function() self:onConnectClicked() end) :align(display.CENTER,display.cx,display.top - 32) :addTo(self) local sendTextLabel = cc.ui.UIPushButton.new() :setButtonLabel(cc.ui.UILabel.new({text= "send text",size = 32})) :onButtonClicked(function() self:onSendTextClicked() end) :align(display.CENTER,display.top - 64) :addTo(self) local sendBinaryLabel = cc.ui.UIPushButton.new() :setButtonLabel(cc.ui.UILabel.new({text= "send binary",size = 32})) :onButtonClicked(function() self:onSendBinaryClicked() end) :align(display.CENTER,display.top - 96) :addTo(self) end function MainScene:onOpen(event) print("connected") end function MainScene:onMessage(event) if WebSockets.BINARY_MESSAGE == event.messageType then printf("receive binary msg: len = %s,binary = %s",string.len(event.message), bin2hex(event.message)) else printf("receive text msg: %s",event.message) end end function MainScene:onClose(event) self.websocket = nil end function MainScene:onError(event) printf("error %s",event.error) self.websocket = nil end function MainScene:onConnectClicked() if self.websocket then return end self.websocket = WebSockets.new("ws://echo.websocket.org") self.websocket:addEventListener(WebSockets.OPEN_EVENT,handler(self, self.onOpen)) self.websocket:addEventListener(WebSockets.MESSAGE_EVENT, self.onMessage)) self.websocket:addEventListener(WebSockets.CLOSE_EVENT, self.onClose)) self.websocket:addEventListener(WebSockets.ERROR_EVENT, self.onError)) end function MainScene:onSendTextClicked() if not self.websocket then print("not connected") return end local text = "hello" .. tostring(math.random()) if self.websocket:send(text) then printf("send text msg: %s",text) end end function MainScene:onSendBinaryClicked() if not self.websocket then print("not connected") return end local t = {} for i = 1,math.random(4,8) do t[#t + 1] = string.char(math.random(0,31)) end local binary = table.concat(t) if self.websocket:send(binary, WebSockets.BINARY_MESSAGE) then printf("send binary msg: len = %d,string.len(binary), bin2hex(binary)) end end return MainScene 4.详解MainScene类中主要的构造函数和其他处理函数。 构造函数创建3个Label分别是 Connect,send text,send binary. 该Label均可以点击,点击后分别调用 onConnectClicked,onSendTextClicked,onSendBinaryClicked函数。 其中: onConnectClicked函数 判断是否才能在self.websocket变量,如果存在则返回,不存在则进行创建。 同时对创建返回的对象添加事件OPEN_EVENT,MESSAGE_EVENT,CLOSE_EVENT,ERROR_EVENT 具体如下: if self.websocket then return end self.websocket = WebSockets.new("ws://echo.websocket.org") self.websocket:addEventListener(WebSockets.OPEN_EVENT, self.onOpen)) self.websocket:addEventListener(WebSockets.MESSAGE_EVENT, self.onMessage)) self.websocket:addEventListener(WebSockets.CLOSE_EVENT, self.onClose)) self.websocket:addEventListener(WebSockets.ERROR_EVENT, self.onError)) 事件对应的函数是onOpen,onMessage,onClose,onError。 其中self.websocket = WebSockets.new("ws://echo.websocket.org") 命令是创建一个连接对象,地址"ws://echo.websocket.org"是测试网址。 这里主要需要介绍的是onMessage函数,该函数在接受到数据后调用,通过判断是否是BINARY_MESSAGE进行输出。 4.1onSendTextClicked函数判断是否存在对象,如果存在则发送字符串。 4.2onSendBinaryClicked函数同onSendTextClicked函数,不过发送的是二进制文件。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |