-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclientserver.lua
149 lines (130 loc) · 3.7 KB
/
clientserver.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
local protocol
local name
local function parse (str)
local f, args = nil, {}
for token in string.gmatch(str, '[^|]+') do
if not f then f = token else
table.insert(args, token)
end
end
return f, args
end
local clients = {}
local function client_up (sid, name)
-- a new client comes to the network.
rednet.send(sid, 'server_id|'..os.computerID(), protocol)
end
local function connect(sid, name)
table.insert(clients, sid)
print('Registered client:' .. sid .. ' name:' .. name)
print('Total clients: ' .. #clients)
rednet.send(sid, 'connect_done', protocol)
end
local server
-- server authoritative answer
local function server_up (sid)
print('Server announcing, connecting to: ' .. sid)
rednet.send(sid, 'connect|' .. name, protocol)
end
-- new client, inform of our server id
local function peer_up (sid)
if server then
print('Peer:'..sid..' is announcing. Replying with server id:'..server)
rednet.send(sid, 'server_id|' .. server, protocol)
end
end
-- non-authoritatve answer, connect explicitely.
local function server_id (sid, serverId)
if not server then
print( 'Peer:' .. sid .. ' points to Server:' .. serverId);
if tonumber(serverId) ~= os.getComputerID() then
local server = tonumber(serverId)
print( 'Connecting to: ' .. server)
rednet.send(tonumber(server), 'connect|'..name, protocol)
end
end
end
-- server connect confirmation
local function connect_done (sid)
server = sid
print('Connected to server: ' .. sid)
end
local clientCommands = {
server_up = server_up,
client_up = peer_up,
server_id = server_id,
connect_done = connect_done
}
local serverCommands = {
client_up = client_up,
connect = connect
}
local function loop (commandTable, timerFunc, delay)
assert(commandTable)
while true do
local sid, msg, p;
if timerFunc then
repeat
sid, msg, p = rednet.receive(protocol, delay or 30)
timerFunc()
until sid
else
sid, msg, p = rednet.receive(protocol);
end
assert(p == protocol)
--print('network: ' .. msg)
cmd, args = parse(msg)
local func = commandTable[cmd]
if func then
func(sid, unpack(args))
end
end
end
function addCommandTable (source, commands)
if source == 'server' then
for k,v in pairs(commands) do
serverCommands[k] = v
end
end
end
function send (message)
if server then
rednet.send( tonumber(server), message, protocol);
end
end
function run (role, _protocol, timerFunc, delay)
print( 'Client/Server - Sample' )
print( 'We are computer: ' .. os.getComputerID())
protocol = _protocol
assert(role == 'client' or role == 'server', 'Specify "client" or "server"')
assert(protocol, 'Specify a server')
--assert(modemLocation == 'left' or modemLocation == 'right'
-- or modemLocation == 'top' or modemLocation == 'bottom'
-- or modemLocation == 'front' or modemLocation == 'back', 'Specify side for the rednet conenction.');
local modemLocation = peripheral.find('modem', function (n,o) return o.isWireless() end );
modemLocation.open(os.getComputerID())
modemLocation.open(65535)
--rednet.open(modemLocation)
if role == 'server' then
local hosts = {rednet.lookup(protocol, 'server')}
local thisAsHost = hosts[1] == os.computerID()
assert(thisAsHost or 0 == #hosts, 'Another server exists.')
name = 'server'
else
name = 'client-'..os.computerID()
end
rednet.host(protocol, name)
print('Registered '..name..' on protocol '..protocol)
if role == 'server' then
-- collect existing clients
print('Annoucing server on ' .. protocol)
rednet.broadcast('server_up', protocol)
print('Running...')
loop(serverCommands, timerFunc, delay)
else
print('Announcing client on ' .. protocol)
rednet.broadcast('client_up|'..name, protocol)
print('Running...')
loop(clientCommands, timerFunc, delay)
end
end