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
|
local cqueues = require 'cqueues'
local socket = require 'cqueues.socket'
local class = require 'r.class'
local BasePylon = require 'pylon'
local Channel = require 'channel'
local Nanochat = class.extend(BasePylon)
function Nanochat:init()
self:_check_fields "server port poll"
end
function Nanochat:_connect()
self.sock = socket.connect(self.server, tonumber(self.port))
self.sock:write("LAST 0\n")
self.sock:read("*l") -- discard count
self.lastid = tonumber(assert(self.sock:read("*l")))
self.usids = {}
end
function Nanochat:recving()
while true do
self.sock:write("SKIP "..self.lastid.."\n")
local deliverables = {} -- holey
local n = tonumber(assert(self.sock:read("*l")))
for i=1,n do
local msg = assert(self.sock:read("*l"))
local chan, msgi = msg:match("^([^ ]+) ()")
if chan then
local sender, body = msg:match("^([^:]+): (.+)$", msgi)
if sender then
deliverables[i] = { source_channel=Channel(self, chan), sender=sender, body=body }
else
deliverables[i] = { source_channel=Channel(self, chan), sender="", body=msg:sub(msgi,-1) }
end
else
-- ignore messages without a channel, they stay nanochat-local
end
end
local s = self.sock:read("*l")
self.lastid = tonumber(assert(s))
for i=1,n do
local msg = deliverables[i] ; if msg then
local id = i - n + self.lastid
if self.usids[id] then
self.usids[id] = nil
else
self.log:proto('<', msg.source_channel.descriptor, msg.sender, msg.body)
self.wilson:deliver(msg)
end
end
end
cqueues.sleep(tonumber(self.poll))
end
end
function Nanochat:sending()
for dest_channel, message in self.inbox:iter() do
self.log:proto('>',dest_channel,message.sender,message.body)
assert(self.sock:write("SEND "..dest_channel.descriptor.." ["..message.source_channel.pylon.shortname.."] "..message.sender..": "..message.body.."\n"))
local id = tonumber(assert(self.sock:read("*l")))
self.usids[id] = true
end
end
return Nanochat
|