15 stream:debug("Increasing handled stanzas to %d for %s", handled_stanza_count, stanza:top_tag()); |
15 stream:debug("Increasing handled stanzas to %d for %s", handled_stanza_count, stanza:top_tag()); |
16 end |
16 end |
17 end |
17 end |
18 |
18 |
19 local function on_disconnect() |
19 local function on_disconnect() |
|
20 stream:debug("smacks: connection lost"); |
20 stream.stream_management_supported = nil; |
21 stream.stream_management_supported = nil; |
21 if stream.resumption_token then |
22 if stream.resumption_token then |
|
23 stream:debug("smacks: have resumption token, reconnecting in 1s..."); |
22 stream.authenticated = nil; |
24 stream.authenticated = nil; |
23 verse.add_task(1, function () |
25 verse.add_task(1, function () |
24 stream:connect(stream.connect_host or stream.host, stream.connect_port or 5222); |
26 stream:connect(stream.connect_host or stream.host, stream.connect_port or 5222); |
25 end); |
27 end); |
26 return true; |
28 return true; |
27 end |
29 end |
28 end |
30 end |
29 |
31 |
30 local function handle_sm_command(stanza) |
32 local function handle_sm_command(stanza) |
31 if stanza.name == "r" then -- Request for acks for stanzas we received |
33 if stanza.name == "r" then -- Request for acks for stanzas we received |
|
34 stream:debug("Ack requested... acking %d handled stanzas", handled_stanza_count); |
32 stream:send(verse.stanza("a", { xmlns = xmlns_sm, h = tostring(handled_stanza_count) })); |
35 stream:send(verse.stanza("a", { xmlns = xmlns_sm, h = tostring(handled_stanza_count) })); |
33 elseif stanza.name == "a" then -- Ack for stanzas we sent |
36 elseif stanza.name == "a" then -- Ack for stanzas we sent |
34 local new_ack = tonumber(stanza.attr.h); |
37 local new_ack = tonumber(stanza.attr.h); |
35 if new_ack > last_ack then |
38 if new_ack > last_ack then |
36 local old_unacked = #outgoing_queue; |
39 local old_unacked = #outgoing_queue; |
62 if stanza.attr.id then |
65 if stanza.attr.id then |
63 stream.resumption_token = stanza.attr.id; |
66 stream.resumption_token = stanza.attr.id; |
64 stream:hook("disconnected", on_disconnect, 100); |
67 stream:hook("disconnected", on_disconnect, 100); |
65 end |
68 end |
66 elseif stanza.name == "resumed" then |
69 elseif stanza.name == "resumed" then |
|
70 --TODO: Check h of the resumed element, discard any acked stanzas from |
|
71 -- our queue (to prevent duplicates), then re-send any lost stanzas. |
67 stream:debug("Resumed successfully"); |
72 stream:debug("Resumed successfully"); |
68 stream:event("resumed"); |
73 stream:event("resumed"); |
69 else |
74 else |
70 stream:warn("Don't know how to handle "..xmlns_sm.."/"..stanza.name); |
75 stream:warn("Don't know how to handle "..xmlns_sm.."/"..stanza.name); |
71 end |
76 end |
72 end |
77 end |
73 |
78 |
74 local function on_bind_success() |
79 local function on_bind_success() |
75 if not stream.smacks then |
80 if not stream.smacks then |
76 --stream:unhook("bind-success", on_bind_success); |
81 --stream:unhook("bind-success", on_bind_success); |
|
82 stream:debug("smacks: sending enable"); |
77 stream:send(verse.stanza("enable", { xmlns = xmlns_sm, resume = "true" })); |
83 stream:send(verse.stanza("enable", { xmlns = xmlns_sm, resume = "true" })); |
78 end |
84 end |
79 end |
85 end |
80 |
86 |
81 local function on_features(features) |
87 local function on_features(features) |
82 if features:get_child("sm", xmlns_sm) then |
88 if features:get_child("sm", xmlns_sm) then |
83 stream.stream_management_supported = true; |
89 stream.stream_management_supported = true; |
84 if stream.smacks and stream.bound then -- Already enabled in a previous session - resume |
90 if stream.smacks and stream.bound then -- Already enabled in a previous session - resume |
|
91 stream:debug("Resuming stream with %d handled stanzas", handled_stanza_count); |
85 stream:send(verse.stanza("resume", { xmlns = xmlns_sm, |
92 stream:send(verse.stanza("resume", { xmlns = xmlns_sm, |
86 h = handled_stanza_count, previd = stream.resumption_token })); |
93 h = handled_stanza_count, previd = stream.resumption_token })); |
87 return true; |
94 return true; |
88 else |
95 else |
89 stream:hook("bind-success", on_bind_success, 1); |
96 stream:hook("bind-success", on_bind_success, 1); |