-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathtcp_thread_client.lua
More file actions
88 lines (80 loc) · 2.56 KB
/
tcp_thread_client.lua
File metadata and controls
88 lines (80 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
local socket=require'socket'
---@type Zenitha.Json
local JSON=require((...)..'json')
local function printf(str,...) print(str:format(...)) end
local C_confCHN=love.thread.getChannel('TCP_c_config')
local C_rspsCHN=love.thread.getChannel('TCP_c_response')
local C_sendCHN=love.thread.getChannel('TCP_c_send')
local C_recvCHN=love.thread.getChannel('TCP_c_receive')
---@type LuaSocket.client
local client
---Send datapack with sender's ID
---@param pack Zenitha.TCP.MsgPack
local function sendMessage(pack)
local suc,dataStr=pcall(JSON.encode,pack)
if not suc then
printf("Error in encoding data to json: %s",dataStr)
return
end
client:send(dataStr..'\n')
end
local partialDataBuffer=''
local function clientLoop()
while true do
-- Process config action
---@type Zenitha.TCP.ConfigMsg
local cfg=C_confCHN:pop()
if cfg then
if cfg.action=='close' then
client:close()
printf("[TCP_C] Disconnected from server")
return
elseif cfg.action=='subTopic' then
sendMessage{req='topic.sub',data=cfg.data}
elseif cfg.action=='unsubTopic' then
sendMessage{req='topic.unsub',data=cfg.data}
end
end
-- Send Data
---@type Zenitha.TCP.MsgPack
local pack=C_sendCHN:pop()
if pack then sendMessage(pack) end
-- Receive data
local message,err,partial=client:receive('*l')
if message then
message=partialDataBuffer..message
partialDataBuffer=''
local suc,recvPack=pcall(JSON.decode,message) ---@type boolean, Zenitha.TCP.MsgPack
if suc then
C_recvCHN:push(recvPack)
else
printf("[TCP_C] Error in decoding message: %s",recvPack)
end
elseif err=='timeout' then
if partial then
partialDataBuffer=partialDataBuffer..partial
end
elseif err=='closed' then
printf("[TCP_C] Server disconnected")
return
end
end
end
while true do
local ip=C_confCHN:demand()
local port=C_confCHN:demand()
local err
client,err=socket.connect(ip,port)
if err then
C_rspsCHN:push{
success=false,
message=("Cannot bind to %s:%s, reason: %s"):format(ip,port,err),
}
else
printf("[TCP_C] Connected to %s:%s",ip,port)
client:settimeout(0.01)
C_rspsCHN:push{success=true}
clientLoop()
end
C_rspsCHN:push(false)
end