-
Notifications
You must be signed in to change notification settings - Fork 4
/
tcp_server.lua
58 lines (53 loc) · 1.59 KB
/
tcp_server.lua
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
local ctx = require"lib.ctx"
local U = require"lib.util"
local ffi = require"ffi"
local S = require"lib.ljsyscall"
local tcp_server = U.object:new()
function tcp_server:init()
local bufsize = 1024
local buf = S.t.buffer(bufsize)
-- TODO: move specifics into srv-epoll.lua
return ctx.srv:tcp_server(self.host, self.port, {
on_readable = function(this)
local fd = this.socket:getfd()
if fd < 0 then
-- FD already closed?
return
end
local n, err = this.socket:read(buf, bufsize)
if n == 0 then
ctx.srv:del(this.socket)
this.socket:shutdown("rd")
ctx.task{name="tcp_client", function()
if this.data then
local n, v
local f, err = load(function()
n, v = next(this.data, n)
return v
end, "remote Lua code")
if f then
f, err = xpcall(f, debug.traceback, ctx, this.socket)
end
if not f then
U.DEBUG({"tcp_server",fd}, "ERROR: %s\n", err)
end
end
end}:next(function()
this.socket:shutdown("rdwr")
this.socket:close()
end)
elseif n then
if not this.data then this.data = {} end
local data = ffi.string(buf, n)
table.insert(this.data, data)
U.DEBUG({"tcp_server",fd}, "data on socket, got %d bytes:\n%s", n, data)
end
end,
on_error = function(this)
U.ERR({"tcp_server",fd}, "error or EOF for connection")
ctx.srv:del(this.socket)
this.socket:close()
end
})
end
return tcp_server