Software /
code /
prosody
Comparison
net/connect.lua @ 8531:601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 23 Feb 2018 15:53:45 +0000 |
child | 8536:c3f234e4ac23 |
comparison
equal
deleted
inserted
replaced
8530:075df839c110 | 8531:601681acea73 |
---|---|
1 local server = require "net.server"; | |
2 local log = require "util.logger".init("net.connect"); | |
3 local new_id = require "util.id".short; | |
4 | |
5 local pending_connection_methods = {}; | |
6 local pending_connection_mt = { | |
7 __name = "pending_connection"; | |
8 __index = pending_connection_methods; | |
9 __tostring = function (p) | |
10 return "<pending connection "..p.id.." to "..tostring(p.target_resolver.hostname)..">"; | |
11 end; | |
12 }; | |
13 | |
14 function pending_connection_methods:log(level, message, ...) | |
15 log(level, "[pending connection %s] "..message, self.id, ...); | |
16 end | |
17 | |
18 -- pending_connections_map[conn] = pending_connection | |
19 local pending_connections_map = {}; | |
20 | |
21 local pending_connection_listeners = {}; | |
22 | |
23 local function attempt_connection(p) | |
24 p:log("debug", "Checking for targets..."); | |
25 if p.conn then | |
26 pending_connections_map[p.conn] = nil; | |
27 p.conn = nil; | |
28 end | |
29 p.target_resolver:next(function (conn_type, ip, port, extra) | |
30 p:log("debug", "Next target to try is %s:%d", ip, port); | |
31 local conn = assert(server.addclient(ip, port, pending_connection_listeners, p.options.pattern, p.options.sslctx, conn_type, extra)); | |
32 p.conn = conn; | |
33 pending_connections_map[conn] = p; | |
34 end); | |
35 end | |
36 | |
37 function pending_connection_listeners.onconnect(conn) | |
38 local p = pending_connections_map[conn]; | |
39 if not p then | |
40 log("warn", "Successful connection, but unexpected! Closing."); | |
41 conn:close(); | |
42 return; | |
43 end | |
44 pending_connections_map[conn] = nil; | |
45 p:log("debug", "Successfully connected"); | |
46 if p.listeners.onattach then | |
47 p.listeners.onattach(conn, p.data); | |
48 end | |
49 conn:setlistener(p.listeners); | |
50 return p.listeners.onconnect(conn); | |
51 end | |
52 | |
53 function pending_connection_listeners.ondisconnect(conn, reason) | |
54 local p = pending_connections_map[conn]; | |
55 if not p then | |
56 log("warn", "Failed connection, but unexpected!"); | |
57 return; | |
58 end | |
59 p:log("debug", "Connection attempt failed"); | |
60 attempt_connection(p); | |
61 end | |
62 | |
63 local function connect(target_resolver, listeners, options, data) | |
64 local p = setmetatable({ | |
65 id = new_id(); | |
66 target_resolver = target_resolver; | |
67 listeners = assert(listeners); | |
68 options = options or {}; | |
69 cb = cb; | |
70 }, pending_connection_mt); | |
71 | |
72 p:log("debug", "Starting connection process"); | |
73 attempt_connection(p); | |
74 end | |
75 | |
76 return { | |
77 connect = connect; | |
78 }; |