cocos lua 网络框架 (不限于cocos 使用)

socket 用的是luasocket 解包数据用的是lpack
cocos3.15.1默认没有集成lpack,要使用的同学请先集成
协议定义的包头长度是12
包头包括ver,bodySize,cmd
依次是版本号,报文大小,命令号
本框架大多思路来自http://blog.csdn.net/eastcowboy/article/details/33334283
好了,以下是框架核心对象SubPack(分包器)

--
-- Author: xiaowa
-- Date: 2017-07-20 01:53:55
--
local socket = require("socket")

require("pack")

VER = 1 --客户端当前版本
local headerSize = 12   --定义包头长

local SubPack = SubPack or class("SubPack")

function SubPack:ctor(address,port,out_fun,close_fun)
    local sock = socket.tcp()
    sock:settimeout(0)
    self.sock = sock
    self.out_fun = out_fun  --超时函数
    self.close_fun = close_fun  --断开函数

    self.recvBuffer = ''
    self.sendBuffer = ''
    self.sendIndex = 1
    self.isConnecting = false
    self.isConnected = false
    --self.continue_nil = 0 --服务端连续发空数据的次数
    if sock:connect(address,port) == 1 then
        print('socket connected')
    else
        self.isConnecting = true
        self.connectTime = socket.gettime()
    end

    self.schedule_ = app.scheduler.scheduleGlobal(handler(self,self.ticks),1/60)
end

function SubPack:ticks()
    if self.isConnecting and socket.gettime() - self.connectTime > 10 then
        -- 连接超时,关闭socket并清理所有变量。
        -- 我还没有发现如何通过luasocket的接口来判断连接超时,所以只好用了这个笨办法
        print(" connect time out ")
        app.scheduler.unscheduleGlobal(self.schedule_)
        self.isConnected = false
        self.isConnecting = false
        self.sock = nil
        self.out_fun()
        return
    end
    local clientSocket = self.sock
    local arr = {clientSocket}

    local r, s, e = socket.select(arr, (self.isConnecting and arr) or nil, 0)

    if r and #r >= 1 and r[1] == clientSocket then
        local recvData, recvError, recvParticialData = clientSocket:receive('*a')

        if recvError == 'closed' then
            -- socket已经断开
            print(" connect close ")
            app.scheduler.unscheduleGlobal(self.schedule_)
            self.isConnected = false
            self.isConnecting = false
            self.sock = nil
            self.close_fun()
            return
        end
        --print((recvData==nil and 'nil') or string.len(recvData),(recvParticialData==nil and 'nil') or string.len(recvParticialData))
        -- 如果是大块数据,可能被拆分成多段,需要多次调用clientSocket:receive才能完成接收。
        -- 因此可以把接收到数据先放到recvBuffer缓存起来。
        if (recvData==nil or string.len(recvData)==0) and (recvParticialData==nil or string.len(recvParticialData)==0) then
            print(" connect close ")
            app.scheduler.unscheduleGlobal(self.schedule_)
            self.isConnected = false
            self.isConnecting = false
            self.sock:close()
            self.sock = nil
            self.close_fun()
            return
        elseif recvData then
            self.recvBuffer = self.recvBuffer .. recvData
        elseif recvParticialData then
            self.recvBuffer = self.recvBuffer .. recvParticialData
        end
        -- 处理缓存起来的数据。
        self:processRecvBuffer()
    end

    if s and #s >= 1 
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值