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 = {}
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
if not deliverables[chan] then deliverables[chan] = {} end
local sender, body = msg:match("^([^:]+): (.+)$", msgi)
if sender then
deliverables[chan][#deliverables[chan]+1] = { i=i, sender=sender, body=body }
else
deliverables[chan][#deliverables[chan]+1] = { i=i, sender=nil, body=msg:sub(msgi,-1) }
end
end
end
local s = self.sock:read("*l")
self.lastid = tonumber(assert(s))
for chan,blorp in pairs(deliverables) do
for _,d in ipairs(blorp) do
local id = d.i - n + self.lastid
d.i = nil
if self.usids[id] then
self.usids[id] = nil
else
self.log:proto('<',chan,d.sender.d.body)
self.wilson:deliver(Channel(self, chan), d)
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.sender..": "..message.body.."\n"))
local id = tonumber(assert(self.sock:read("*l")))
self.usids[id] = true
end
end
return Nanochat
|