-
-
Save xiangyuan/9027caeb8f7be0c1083d8e6372cc3323 to your computer and use it in GitHub Desktop.
lua socket
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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