Skip to content

Instantly share code, notes, and snippets.

@xiangyuan
Forked from zhuzhonghua/client_socket.lua
Created April 1, 2016 06:26
Show Gist options
  • Save xiangyuan/9027caeb8f7be0c1083d8e6372cc3323 to your computer and use it in GitHub Desktop.
Save xiangyuan/9027caeb8f7be0c1083d8e6372cc3323 to your computer and use it in GitHub Desktop.
lua socket
local ClientSocket = {}
local socket = require("socket.core")
local sockInst = nil
-- ------------------------------------------------
local connStatus = nil
local SOCK_STATUS={INIT=1, CONNECTING=2, CONNECTED=3,DISCONNECT=4,FORCEDISCONNECT=5}
local connTime = nil
local tryConnTimes = 0
local recvBuffer = ""
local sendBuffer = ""
local lastSendTime = 0
local lastRecvTime = 0
local heartBeatFunc = nil
local onConnectedFunc = nil
local initSockFunc = nil
function ClientSocket.getConnState()
-- body
return connStatus
end
function ClientSocket.getRecvBuffer()
-- body
return recvBuffer
end
function ClientSocket.skipRecvBuffer(n)
recvBuffer=string.sub(recvBuffer,n+1)
-- body
end
function ClientSocket.sendMsg(opcode, msg, len)
-- body
-- Util:getInst():packMsg 为c++方法,可以使用tolua++生成
sendBuffer = sendBuffer..Util:getInst():packMsg(opcode,msg,len)
lastSendTime = os.time()
end
local function onConnected()
-- body
connStatus = SOCK_STATUS.CONNECTED
tryConnTimes = 0
lastSendTime = os.time()
lastRecvTime = os.time()
-- 调用设置的回调函数
onConnectedFunc()
end
-- 出现异常才会调用,就不要再重新连接了
function ClientSocket.onForceDisconnect()
-- body
connStatus = SOCK_STATUS.FORCEDISCONNECT
ClientSocket.initSock()
end
function ClientSocket.onDisconnect()
-- body
connStatus = SOCK_STATUS.DISCONNECT
ClientSocket.initSock()
end
local function tryConnect()
-- body
tryConnTimes=tryConnTimes+1
connTime = os.time()
local __succ, __status = sockInst:connect("127.0.0.1", 40234)
if __succ == 1 or __status == "already connected" then
print('tryconnect socket connected')
onConnected()
else
print('====================================socket connected fail try again');
connStatus = SOCK_STATUS.CONNECTING
end
end
local function handleOutData()
-- body
if #sendBuffer >= 1 then
local num, err, num2 = sockInst:send(sendBuffer)
if err == 'closed' then
print('send socket disconnect ')
ClientSocket.onDisconnect()
return
end
if num then
print('socket send msg len '..num)
sendBuffer = string.sub(sendBuffer,num+1)
elseif num2 then
print('socket send error '..err.." msglen "..num2)
sendBuffer = string.sub(sendBuffer,num2+1)
else
print('socket send msg err '..err)
end
end
end
function ClientSocket.select()
if (connStatus == SOCK_STATUS.DISCONNECT or connStatus == SOCK_STATUS.CONNECTING) and os.time()-connTime > 1 then
tryConnect()
return
end
if connStatus == SOCK_STATUS.CONNECTED then
-- 调用回调
heartBeatFunc()
end
if connStatus == SOCK_STATUS.CONNECTING or connStatus == SOCK_STATUS.CONNECTED then
-- body
local arr = {sockInst}
local r, s, e = socket.select(arr, arr, 0)
if r and #r >= 1 and r[1] == sockInst then
local recvData, recvError, recvParticialData = sockInst:receive(1024);
if recvError == 'closed' then
print('recv socket disconnect ')
ClientSocket.onDisconnect()
return;
end
if recvData and #recvData > 0 then
print('recvdata len='..#recvData)
recvBuffer = recvBuffer .. recvData
elseif recvParticialData and #recvParticialData > 0 then
print('recvparticialdata len='..#recvParticialData)
recvBuffer = recvBuffer .. recvParticialData
end
end
if s and #s >= 1 and s[1] == sockInst then
if connStatus==SOCK_STATUS.CONNECTING then
-- 执行到此,说明连接已经成功了
--print('select send socket connect success');
--onConnected()
end
-- 可以调用send
if connStatus == SOCK_STATUS.CONNECTED then
handleOutData()
end
end
end
end
function ClientSocket.initSock()
if sockInst then
sockInst:close()
end
sockInst = socket.tcp();
sockInst:settimeout(0);
sockInst:setoption('keepalive', true)
-- 调用回调
initSockFunc()
end
function ClientSocket.init(hb, connSucc, initsock)
heartBeatFunc=hb
onConnectedFunc=connSucc
initSockFunc=initsock
connStatus = SOCK_STATUS.INIT
ClientSocket.initSock()
tryConnect()
end
function ClientSocket.exit()
sockInst:close()
sockInst = nil
end
local function onConnected()
-- body
-- TODO
end
local MSG_HEADER_LEN = 6
function handleInData()
-- body
local recvBuffer=ClientSocket.getRecvBuffer()
if #recvBuffer >= MSG_HEADER_LEN then
-- TODO C++ 提供的方法 Util:getInst():getPacketHead
local headerInfo = Util:getInst():getPacketHead(recvBuffer, MSG_HEADER_LEN)
if #recvBuffer >= MSG_HEADER_LEN+headerInfo.msgSize then
local body = string.sub(recvBuffer,MSG_HEADER_LEN+1,MSG_HEADER_LEN+headerInfo.msgSize)
local handle = Handler[headerInfo.opCode]
if handle then
handle(headerInfo.opCode, body)
else
print("no such handler "..headerInfo.opCode)
end
ClientSocket.skipRecvBuffer(MSG_HEADER_LEN+headerInfo.msgSize)
lastRecvTime = os.time()
end
end
end
local function heartBeat()
-- body
if os.time() - lastSendTime > 10 then
-- TODO
-- ClientSocket.sendMsg(1,"1",1)
print("sendheartbeat")
end
if os.time() - lastRecvTime > 20 then
ClientSocket.onDisconnect()
print("time too long no recv msg")
end
end
local function init()
ClientSocket.init(heartBeat, onConnected, initSockcb)
end
local function exit()
ClientSocket.exit()
end
local function update()
ClientSocket.select()
if ClientSocket.getConnState() == SOCK_STATUS.CONNECTED then
handleInData()
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment