Skip to content

Commit 7318bbb

Browse files
committed
support connecting by socket with --socket=PORT
1 parent d7e5982 commit 7318bbb

File tree

8 files changed

+175
-11
lines changed

8 files changed

+175
-11
lines changed

changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# changelog
22

3+
## 3.6.20
4+
* `NEW` support connecting by socket with `--socket=PORT`
5+
36
## 3.6.19
47
`2023-4-26`
58
* `FIX` commandline parameter `checklevel` may not work

script/brave/work.lua

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
local brave = require 'brave.brave'
22

3-
brave.on('loadProto', function ()
3+
brave.on('loadProtoByStdio', function ()
44
local jsonrpc = require 'jsonrpc'
55
while true do
66
local proto, err = jsonrpc.decode(io.read)
@@ -13,6 +13,37 @@ brave.on('loadProto', function ()
1313
end
1414
end)
1515

16+
brave.on('loadProtoBySocket', function (fdHandle)
17+
local jsonrpc = require 'jsonrpc'
18+
local socket = require 'bee.socket'
19+
local thread = require 'bee.thread'
20+
local fd = socket.fd(fdHandle)
21+
local buf = ''
22+
while true do
23+
local proto, err = jsonrpc.decode(function (len)
24+
while true do
25+
if #buf >= len then
26+
local res = buf:sub(1, len)
27+
buf = buf:sub(len + 1)
28+
return res
29+
end
30+
local data = fd:recv()
31+
if data then
32+
buf = buf .. data
33+
else
34+
thread.sleep(0.01)
35+
end
36+
end
37+
end)
38+
--log.debug('loaded proto', proto.method)
39+
if not proto then
40+
brave.push('protoerror', err)
41+
return
42+
end
43+
brave.push('proto', proto)
44+
end
45+
end)
46+
1647
brave.on('timer', function (time)
1748
local thread = require 'bee.thread'
1849
while true do

script/global.d.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,7 @@ COMPILECORES = 0
7373
-- TODO: delete this after new config
7474
---@diagnostic disable-next-line: lowercase-global
7575
jit = false
76+
77+
-- connect to client by socket
78+
---@type integer
79+
SOCKET = 0

script/jsonrpc.lua

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,23 @@ function m.encode(pack)
1414
return buf
1515
end
1616

17+
---@param reader fun(arg: integer):string
1718
local function readProtoHead(reader)
1819
local head = {}
20+
local line = ''
1921
while true do
20-
local line = reader 'L'
21-
if line == nil then
22+
local char = reader(1)
23+
if char == nil then
2224
-- 说明管道已经关闭了
2325
return nil, 'Disconnected!'
2426
end
27+
line = line .. char
2528
if line == '\r\n' then
2629
break
2730
end
31+
if line:sub(-2) ~= '\r\n' then
32+
goto continue
33+
end
2834
local k, v = line:match '^([^:]+)%s*%:%s*(.+)\r\n$'
2935
if not k then
3036
return nil, 'Proto header error: ' .. line
@@ -33,10 +39,13 @@ local function readProtoHead(reader)
3339
v = tonumber(v)
3440
end
3541
head[k] = v
42+
line = ''
43+
::continue::
3644
end
3745
return head
3846
end
3947

48+
---@param reader fun(arg: integer):string
4049
function m.decode(reader)
4150
local head, err = readProtoHead(reader)
4251
if not head then

script/meta/bee/socket.lua

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---@meta
2+
3+
---@alias bee.socket.protocol
4+
---| 'tcp'
5+
---| 'udp'
6+
---| 'unix'
7+
---| 'tcp6'
8+
---| 'udp6'
9+
10+
---@class bee.socket
11+
---@overload fun(protocol: bee.socket.protocol): bee.socket.fd?, string?
12+
local socket = {}
13+
14+
---@param readfds? bee.socket.fd[]
15+
---@param writefds? bee.socket.fd[]
16+
---@param timeout number
17+
---@return bee.socket.fd[] # readfds
18+
---@return bee.socket.fd[] # writefds
19+
function socket.select(readfds, writefds, timeout) end
20+
21+
---@param handle lightuserdata
22+
---@return bee.socket.fd
23+
function socket.fd(handle) end
24+
25+
---@class bee.socket.fd
26+
local fd = {}
27+
28+
---@param addr string
29+
---@param port? integer
30+
---@return boolean
31+
---@return string?
32+
function fd:bind(addr, port) end
33+
34+
function fd:close() end
35+
36+
---@return boolean
37+
---@return string?
38+
function fd:listen() end
39+
40+
---@param addr string
41+
---@param port integer
42+
---@return boolean
43+
---@return string?
44+
function fd:connect(addr, port) end
45+
46+
---@param len? integer
47+
---@return string | false
48+
function fd:recv(len) end
49+
50+
---@param content string
51+
function fd:send(content) end
52+
53+
---@return lightuserdata
54+
function fd:handle() end
55+
56+
---@return boolean
57+
function fd:status() end
58+
59+
---@return bee.socket.fd
60+
function fd:accept() end
61+
62+
return socket

script/meta/bee/thread.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---@meta
2+
3+
---@class bee.thread
4+
local thread = {}
5+
6+
---@param time number
7+
function thread.sleep(time) end
8+
9+
---@param name string
10+
function thread.newchannel(name) end
11+
12+
---@param name string
13+
---@return bee.thread.channel
14+
function thread.channel(name) end
15+
16+
---@param script string
17+
---@return bee.thread.thread
18+
function thread.thread(script) end
19+
20+
---@class bee.thread.channel
21+
local channel = {}
22+
23+
function channel:push(...) end
24+
25+
---@return ...
26+
function channel:pop() end
27+
28+
---@return ...
29+
function channel:bpop() end
30+
31+
---@class bee.thread.thread
32+
33+
return thread

script/proto/proto.lua

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
local subprocess = require 'bee.subprocess'
2+
local socket = require 'bee.socket'
23
local util = require 'utility'
34
local await = require 'await'
45
local pub = require 'pub'
56
local jsonrpc = require 'jsonrpc'
67
local define = require 'proto.define'
78
local json = require 'json'
89
local inspect = require 'inspect'
10+
local thread = require 'bee.thread'
911

1012
local reqCounter = util.counter()
1113

@@ -29,6 +31,9 @@ local m = {}
2931
m.ability = {}
3032
m.waiting = {}
3133
m.holdon = {}
34+
m.mode = 'stdio'
35+
---@type bee.socket.fd
36+
m.fd = nil
3237

3338
function m.getMethodName(proto)
3439
if proto.method:sub(1, 2) == '$/' then
@@ -46,7 +51,11 @@ end
4651
function m.send(data)
4752
local buf = jsonrpc.encode(data)
4853
logSend(buf)
49-
io.write(buf)
54+
if m.mode == 'stdio' then
55+
io.write(buf)
56+
elseif m.mode == 'socket' then
57+
m.fd:send(buf)
58+
end
5059
end
5160

5261
function m.response(id, res)
@@ -219,12 +228,20 @@ function m.doResponse(proto)
219228
waiting.resume(proto.result)
220229
end
221230

222-
function m.listen()
223-
subprocess.filemode(io.stdin, 'b')
224-
subprocess.filemode(io.stdout, 'b')
225-
io.stdin:setvbuf 'no'
226-
io.stdout:setvbuf 'no'
227-
pub.task('loadProto')
231+
function m.listen(mode, socketPort)
232+
m.mode = mode
233+
if mode == 'stdio' then
234+
subprocess.filemode(io.stdin, 'b')
235+
subprocess.filemode(io.stdout, 'b')
236+
io.stdin:setvbuf 'no'
237+
io.stdout:setvbuf 'no'
238+
pub.task('loadProtoByStdio')
239+
elseif mode == 'socket' then
240+
local fd = assert(socket('tcp'))
241+
fd:connect('127.0.0.1', socketPort)
242+
m.fd = fd
243+
pub.task('loadProtoBySocket', fd:handle())
244+
end
228245
end
229246

230247
return m

script/service/service.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,12 @@ function m.start()
267267
if COMPILECORES and COMPILECORES > 0 then
268268
pub.recruitBraves(COMPILECORES, 'compile')
269269
end
270-
proto.listen()
270+
if SOCKET then
271+
assert(math.tointeger(SOCKET), '`socket` must be integer')
272+
proto.listen('socket', SOCKET)
273+
else
274+
proto.listen('stdio')
275+
end
271276
m.report()
272277
m.testVersion()
273278
m.lockCache()

0 commit comments

Comments
 (0)