13 -- State for incoming stanzas |
13 -- State for incoming stanzas |
14 local handled_stanza_count = 0; |
14 local handled_stanza_count = 0; |
15 |
15 |
16 -- Catch incoming stanzas |
16 -- Catch incoming stanzas |
17 local function incoming_stanza(stanza) |
17 local function incoming_stanza(stanza) |
18 if stanza.attr.xmlns == "jabber:client" or not stanza.attr.xmlns then |
18 if stream.smacks and (stanza.attr.xmlns == "jabber:client" or not stanza.attr.xmlns) then |
19 handled_stanza_count = handled_stanza_count + 1; |
19 handled_stanza_count = handled_stanza_count + 1; |
20 stream:debug("Increasing handled stanzas to %d for %s", handled_stanza_count, stanza:top_tag()); |
20 stream:debug("Increasing handled stanzas to %d for %s", handled_stanza_count, stanza:top_tag()); |
21 end |
21 end |
22 end |
22 end |
23 |
23 |
24 -- Catch outgoing stanzas |
24 -- Catch outgoing stanzas |
25 local function outgoing_stanza(stanza) |
25 local function outgoing_stanza(stanza) |
26 -- NOTE: This will not behave nice if stanzas are serialized before this point |
26 -- NOTE: This will not behave nice if stanzas are serialized before this point |
27 if stanza.name and not stanza.attr.xmlns then |
27 if stream.smacks and (stanza.name and not stanza.attr.xmlns) then |
28 -- serialize stanzas in order to bypass this on resumption |
28 -- serialize stanzas in order to bypass this on resumption |
29 outgoing_queue[#outgoing_queue+1] = tostring(stanza); |
29 outgoing_queue[#outgoing_queue+1] = tostring(stanza); |
30 last_stanza_time = now(); |
30 last_stanza_time = now(); |
31 if not timer_active then |
31 if not timer_active then |
32 timer_active = true; |
32 timer_active = true; |
62 end |
62 end |
63 |
63 |
64 -- Graceful shutdown |
64 -- Graceful shutdown |
65 local function on_close() |
65 local function on_close() |
66 stream.resumption_token = nil; |
66 stream.resumption_token = nil; |
67 stream:unhook("disconnected", on_disconnect); |
|
68 end |
67 end |
69 |
68 |
70 local function handle_sm_command(stanza) |
69 local function handle_sm_command(stanza) |
71 if stanza.name == "r" then -- Request for acks for stanzas we received |
70 if stanza.name == "r" then -- Request for acks for stanzas we received |
72 stream:debug("Ack requested... acking %d handled stanzas", handled_stanza_count); |
71 stream:debug("Ack requested... acking %d handled stanzas", handled_stanza_count); |
86 elseif stanza.name == "enabled" then |
85 elseif stanza.name == "enabled" then |
87 stream.pre_smacks_features = nil; |
86 stream.pre_smacks_features = nil; |
88 |
87 |
89 if stanza.attr.id then |
88 if stanza.attr.id then |
90 stream.resumption_token = stanza.attr.id; |
89 stream.resumption_token = stanza.attr.id; |
91 stream:hook("closed", on_close, 100); |
|
92 stream:hook("disconnected", on_disconnect, 100); |
|
93 end |
90 end |
94 elseif stanza.name == "resumed" then |
91 elseif stanza.name == "resumed" then |
95 stream.pre_smacks_features = nil; |
92 stream.pre_smacks_features = nil; |
96 local new_ack = tonumber(stanza.attr.h); |
93 local new_ack = tonumber(stanza.attr.h); |
97 if new_ack > last_ack then |
94 if new_ack > last_ack then |
126 stream:warn("Don't know how to handle "..xmlns_sm.."/"..stanza.name); |
123 stream:warn("Don't know how to handle "..xmlns_sm.."/"..stanza.name); |
127 end |
124 end |
128 end |
125 end |
129 |
126 |
130 local function on_bind_success() |
127 local function on_bind_success() |
131 if not stream.smacks then |
128 if stream.stream_management_supported and not stream.smacks then |
132 --stream:unhook("bind-success", on_bind_success); |
129 --stream:unhook("bind-success", on_bind_success); |
133 stream:debug("smacks: sending enable"); |
130 stream:debug("smacks: sending enable"); |
134 stream:send(verse.stanza("enable", { xmlns = xmlns_sm, resume = "true" })); |
131 stream:send(verse.stanza("enable", { xmlns = xmlns_sm, resume = "true" })); |
135 stream.smacks = true; |
132 stream.smacks = true; |
136 |
|
137 -- Catch stanzas |
|
138 stream:hook("stanza", incoming_stanza); |
|
139 stream:hook("outgoing", outgoing_stanza); |
|
140 end |
133 end |
141 end |
134 end |
142 |
135 |
143 local function on_features(features) |
136 local function on_features(features) |
144 if features:get_child("sm", xmlns_sm) then |
137 if features:get_child("sm", xmlns_sm) then |
148 stream:debug("Resuming stream with %d handled stanzas", handled_stanza_count); |
141 stream:debug("Resuming stream with %d handled stanzas", handled_stanza_count); |
149 stream:send(verse.stanza("resume", { xmlns = xmlns_sm, |
142 stream:send(verse.stanza("resume", { xmlns = xmlns_sm, |
150 h = tostring(handled_stanza_count), previd = stream.resumption_token })); |
143 h = tostring(handled_stanza_count), previd = stream.resumption_token })); |
151 return true; |
144 return true; |
152 else |
145 else |
153 stream:hook("bind-success", on_bind_success, 1); |
|
154 end |
146 end |
155 end |
147 end |
156 end |
148 end |
157 |
149 |
158 stream:hook("stream-features", on_features, 250); |
150 stream:hook("stream-features", on_features, 250); |
159 stream:hook("stream/"..xmlns_sm, handle_sm_command); |
151 stream:hook("stream/"..xmlns_sm, handle_sm_command); |
|
152 stream:hook("bind-success", on_bind_success, 1); |
|
153 |
|
154 -- Catch stanzas |
|
155 stream:hook("stanza", incoming_stanza); |
|
156 stream:hook("outgoing", outgoing_stanza); |
|
157 |
|
158 stream:hook("closed", on_close, 100); |
|
159 stream:hook("disconnected", on_disconnect, 100); |
|
160 |
160 --stream:hook("ready", on_stream_ready, 500); |
161 --stream:hook("ready", on_stream_ready, 500); |
161 end |
162 end |