-
Notifications
You must be signed in to change notification settings - Fork 1
/
rpc.lua
84 lines (73 loc) · 1.89 KB
/
rpc.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
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
--[[
-------------------------
-- Example usage from Lua
-------------------------
local rpc = require "rpc"
local py = rpc.create()
-- Call 'bar' in connected Python client(s).
py.bar(1,2,3)
-- set up callable function 'fnord'
py.register("fnord", function(a, b)
print("fnord called with", a, b)
end)
----------------------------
-- Example usage from Python
-- (see also hosted.py)
----------------------------
from hosted import node
lua = node.rpc()
# Connect to info-beamer/Lua and run fnord function
lua.fnord("a", "b")
# Register callable function 'bar'
@lua.call
def bar(a, b, c):
print("called from lua", a, b, c)
]]
local function create(endpoints)
endpoints = endpoints or {}
local json = require "json"
local clients = {}
node.set_flag("close_clients", true)
node.event("connect", function(client, prefix)
if prefix == "rpc/python" then
clients[client] = true
end
end)
node.event("disconnect", function(client)
clients[client] = nil
end)
node.event("input", function(line, client)
if clients[client] then
local call = json.decode(line)
local fn = table.remove(call, 1)
if endpoints[fn] then
endpoints[fn](unpack(call))
end
end
end)
local function send_call(call, ...)
local args = {...}
table.insert(args, 1, call)
local pkt = json.encode(args)
local sent = false
for client, _ in pairs(clients) do
sent = true
node.client_write(client, pkt)
end
return sent
end
return setmetatable({
register = function(name, fn)
endpoints[name] = fn
end,
}, {
__index = function(t, call)
return function(...)
return send_call(call, ...)
end
end
})
end
return {
create = create,
}