分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
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的浏览器:
Chrome | Supported in version 4+ |
Firefox | Supported in version 4+ |
Internet Explorer | Supported in version 10+ |
Opera | Supported in version 10+ |
Safari | Supported in version 5+ |
所以这个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_MESSAGEthen
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.cx,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.cx,display.top -96)
:addTo(self)
end
function MainScene:onOpen(event)
print("connected")
end
function MainScene:onMessage(event)
if WebSockets.BINARY_MESSAGE == event.messageTypethen
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,handler(self, self.onMessage))
self.websocket:addEventListener(WebSockets.CLOSE_EVENT,handler(self, self.onClose))
self.websocket:addEventListener(WebSockets.ERROR_EVENT,handler(self, 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, binary = %s",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
具体如下:
ifself.websocket thenreturn 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,handler(self, self.onMessage))
self.websocket:addEventListener(WebSockets.CLOSE_EVENT,handler(self, self.onClose))
self.websocket:addEventListener(WebSockets.ERROR_EVENT,handler(self, self.onError))
事件对应的函数是onOpen,onMessage,onClose,onError。
其中self.websocket = WebSockets.new("ws://echo.websocket.org") 命令是创建一个连接对象,地址"ws://echo.websocket.org"是测试网址。
这里主要需要介绍的是onMessage函数,该函数在接受到数据后调用,通过判断是否是BINARY_MESSAGE进行输出。
4.1 onSendTextClicked函数
判断是否存在对象,如果存在则发送字符串。
4.2 onSendBinaryClicked函数
同onSendTextClicked函数,不过发送的是二进制文件。