SipMSRPApi
Version 48 (Luci Stanescu, 04/15/2010 02:01 pm)
1 | 1 | Adrian Georgescu | = MSRP API = |
---|---|---|---|
2 | 1 | Adrian Georgescu | |
3 | 48 | Luci Stanescu | [[TOC(SipMSRPApi, SipDeveloperGuide, depth=2)]] |
4 | 1 | Adrian Georgescu | |
5 | 31 | Adrian Georgescu | Message Session Relay Protocol (MSRP) is a protocol for transmitting a series of related Instant Messages in the context of a session. Message sessions are treated like any other media stream when set up via a rendezvous or session creation protocol such as the Session Initiation Protocol (SIP). |
6 | 1 | Adrian Georgescu | |
7 | 25 | Adrian Georgescu | * MSRP sessions are defined in [http://tools.ietf.org/html/rfc4975 RFC 4975] |
8 | 25 | Adrian Georgescu | * MSRP relay extension used for NAT traversal of instant messaging and file transfer sessions is defined in [http://tools.ietf.org/html/rfc4976 RFC 4976] |
9 | 1 | Adrian Georgescu | |
10 | 32 | Adrian Georgescu | The MSRP protocol stack is implemented by [http://devel.ag-projects.com/cgi-bin/darcsweb.cgi?r=python-msrplib;a=summary msrplib] Python package. |
11 | 4 | Oliver Bril | |
12 | 33 | Adrian Georgescu | {{{msrplib}}} is based upon [http://twistedmatrix.com twisted] and [http://download.ag-projects.com/SipClient/ eventlet] and provides a set of classes for establishing and managing MSRP connections. |
13 | 1 | Adrian Georgescu | |
14 | 28 | Adrian Georgescu | The library consists of the following modules: |
15 | 1 | Adrian Georgescu | |
16 | 1 | Adrian Georgescu | '''msrplib.transport''':: |
17 | 27 | Adrian Georgescu | Defines {{{MSRPTransport}}} class, which provides low level control over MSRP connections. |
18 | 2 | Redmine Admin | |
19 | 1 | Adrian Georgescu | '''msrplib.connect''':: |
20 | 1 | Adrian Georgescu | Defines means to establish a connection, bind it, and provide an initialized {{{MSRPTransport}}} instance. |
21 | 1 | Adrian Georgescu | |
22 | 1 | Adrian Georgescu | '''msrplib.session''':: |
23 | 1 | Adrian Georgescu | Defines {{{MSRPSession}}} class, which provides high level control over a MSRP connection. |
24 | 1 | Adrian Georgescu | |
25 | 1 | Adrian Georgescu | '''msrplib.protocol''':: |
26 | 42 | Luci Stanescu | Provides representation and parsing of MSRP entities - chunks and MSRP URIs. |
27 | 1 | Adrian Georgescu | |
28 | 48 | Luci Stanescu | == URI == |
29 | 39 | Luci Stanescu | |
30 | 44 | Luci Stanescu | This class is implemented in the {{{msrplib.protocol}}} module and is used to represent an MSRP URI. |
31 | 1 | Adrian Georgescu | |
32 | 48 | Luci Stanescu | === Methods === |
33 | 1 | Adrian Georgescu | |
34 | 39 | Luci Stanescu | '''!__init!__'''(''self'', '''host'''={{{None}}}, '''use_tls'''={{{False}}}, '''user'''={{{None}}}, '''port'''={{{None}}}, '''session_id'''={{{None}}}, '''parameters'''={{{None}}}, '''credentials'''={{{None}}}):: |
35 | 39 | Luci Stanescu | Constructs a new {{{URI}}}. All the arguments specified here are also attributes on the object. For more information on these attributes, see RFC4975. |
36 | 39 | Luci Stanescu | [[BR]]''host'':[[BR]] |
37 | 39 | Luci Stanescu | The hostname or IP address which forms the URI. |
38 | 39 | Luci Stanescu | [[BR]]''use_tls'':[[BR]] |
39 | 39 | Luci Stanescu | Whether this identifies an msrps or msrp URI. |
40 | 39 | Luci Stanescu | [[BR]]''user'':[[BR]] |
41 | 39 | Luci Stanescu | The user part of the URI. |
42 | 39 | Luci Stanescu | [[BR]]''port'':[[BR]] |
43 | 39 | Luci Stanescu | The port in the URI. |
44 | 39 | Luci Stanescu | [[BR]]''session_id'':[[BR]] |
45 | 39 | Luci Stanescu | The session identifier part of the URI. |
46 | 1 | Adrian Georgescu | [[BR]]''parameters'':[[BR]] |
47 | 39 | Luci Stanescu | A {{{dict}}} containing the parameters which will be appended to the URI. |
48 | 39 | Luci Stanescu | [[BR]]''credentials'':[[BR]] |
49 | 1 | Adrian Georgescu | A {{{gnutls.interfaces.twisted.X509Credentials}}} object which will be used if this identifies a TLS URI to authenticate to the other endpoint. |
50 | 39 | Luci Stanescu | |
51 | 48 | Luci Stanescu | == MSRPRelaySettings == |
52 | 1 | Adrian Georgescu | |
53 | 45 | Luci Stanescu | This class is implemented in the {{{msrplib.connect}}} module and is used to specify the MSRP relay which will be used when connecting via a relay (using the {{{ConnectorRelay}}} or {{{AcceptorRelay}}} classes). |
54 | 39 | Luci Stanescu | |
55 | 48 | Luci Stanescu | === Methods === |
56 | 39 | Luci Stanescu | |
57 | 39 | Luci Stanescu | '''!__init!__'''(''self'', '''domain''', '''username''', '''password''', '''host'''={{{None}}}, '''use_tls'''={{{False}}}, '''port'''={{{None}}}, '''credentials'''={{{None}}}):: |
58 | 39 | Luci Stanescu | Constructs a new {{{URI}}}. All the arguments specified here are also attributes on the object. For more information on these attributes, see RFC4975. |
59 | 39 | Luci Stanescu | [[BR]]''domain'':[[BR]] |
60 | 39 | Luci Stanescu | The DNS domain in which to search for a MSRP relay using SRV queries. |
61 | 39 | Luci Stanescu | [[BR]]''username'':[[BR]] |
62 | 39 | Luci Stanescu | The username which will be used to authenticate to the relay. |
63 | 39 | Luci Stanescu | [[BR]]''password'':[[BR]] |
64 | 39 | Luci Stanescu | The password which will be used to authenticate to the relay. |
65 | 39 | Luci Stanescu | [[BR]]''host'':[[BR]] |
66 | 39 | Luci Stanescu | The hostname or IP address of the MSRP relay. |
67 | 1 | Adrian Georgescu | [[BR]]''use_tls'':[[BR]] |
68 | 39 | Luci Stanescu | Whether this identifies an msrps or msrp URI. |
69 | 39 | Luci Stanescu | [[BR]]''port'':[[BR]] |
70 | 1 | Adrian Georgescu | The port in the URI. |
71 | 39 | Luci Stanescu | [[BR]]''credentials'':[[BR]] |
72 | 39 | Luci Stanescu | A {{{gnutls.interfaces.twisted.X509Credentials}}} object which will be used to authenticate to the relay if TLS is used. |
73 | 39 | Luci Stanescu | |
74 | 48 | Luci Stanescu | == ConnectorDirect == |
75 | 39 | Luci Stanescu | |
76 | 44 | Luci Stanescu | This class is implemented in the {{{msrplib.connect}}} module and is used for outbound MSRP connections without a relay. |
77 | 39 | Luci Stanescu | |
78 | 48 | Luci Stanescu | === Methods === |
79 | 39 | Luci Stanescu | |
80 | 39 | Luci Stanescu | '''!__init!__'''(''self'', '''loger'''={{{None}}}):: |
81 | 44 | Luci Stanescu | Constructs a new ConnectorDirect. |
82 | 39 | Luci Stanescu | [[BR]]''logger'':[[BR]] |
83 | 39 | Luci Stanescu | The logger which will be used for this MSRP connection. See the [wiki:SipMSRPApi#Logging Logging] section for more information. |
84 | 39 | Luci Stanescu | |
85 | 39 | Luci Stanescu | '''prepare'''(''self'', '''local_uri'''={{{None}}}):: |
86 | 39 | Luci Stanescu | This method returns a full local path - list of {{{protocol.URI}}} instances, suitable to be put in SDP {{{'a:path'}}} attribute. |
87 | 39 | Luci Stanescu | [[BR]]''local_uri'':[[BR]] |
88 | 39 | Luci Stanescu | This attribute will be used to construct the local path, but other than that it is not used anywhere else in case of the ConnectorDirect. If not provided, one |
89 | 39 | Luci Stanescu | will be automatically generated |
90 | 1 | Adrian Georgescu | |
91 | 1 | Adrian Georgescu | '''complete'''(''self'', '''full_remote_path'''):: |
92 | 39 | Luci Stanescu | This method establishes the connection and binds it (sends an empty chunk to verify each other's From-Path and To-Path). It returns {{{transport.MSRPTransport}}} instance, ready to read and send chunks. |
93 | 1 | Adrian Georgescu | [[BR]]''full_remote_path'':[[BR]] |
94 | 39 | Luci Stanescu | A list of {{{protocol.URI}}} instances, obtained by parsing {{{'a:path'}}} put in SDP by the remote party. |
95 | 1 | Adrian Georgescu | |
96 | 39 | Luci Stanescu | '''cleanup'''(''self''):: |
97 | 39 | Luci Stanescu | This method cleans up after {{{prepare()}}}; it should be called if {{{complete()}}} will not be called for whatever reason. |
98 | 1 | Adrian Georgescu | |
99 | 48 | Luci Stanescu | == ConnectorRelay == |
100 | 1 | Adrian Georgescu | |
101 | 44 | Luci Stanescu | This class is implemented in the {{{msrplib.connect}}} module and is used for outbound MSRP connections using a relay. |
102 | 1 | Adrian Georgescu | |
103 | 48 | Luci Stanescu | === Methods === |
104 | 39 | Luci Stanescu | |
105 | 39 | Luci Stanescu | '''!__init!__'''(''self'', '''relay''', '''loger'''={{{None}}}):: |
106 | 39 | Luci Stanescu | Constructs a new ConnectorRelay. |
107 | 39 | Luci Stanescu | [[BR]]''relay'':[[BR]] |
108 | 39 | Luci Stanescu | An instance of {{{MSRPRelaySettings}}} which identifies the relay which is to be used. |
109 | 39 | Luci Stanescu | [[BR]]''logger'':[[BR]] |
110 | 39 | Luci Stanescu | The logger which will be used for this MSRP connection. See the [wiki:SipMSRPApi#Logging Logging] section for more information. |
111 | 39 | Luci Stanescu | |
112 | 39 | Luci Stanescu | '''prepare'''(''self'', '''local_uri'''={{{None}}}):: |
113 | 39 | Luci Stanescu | This method returns a full local path - list of {{{protocol.URI}}} instances, suitable to be put in SDP {{{'a:path'}}} attribute. |
114 | 39 | Luci Stanescu | [[BR]]''local_uri'':[[BR]] |
115 | 1 | Adrian Georgescu | This attribute will be used to construct the local path, but other than that it is not used anywhere else in case of the ConnectorRelay. If not provided, one |
116 | 39 | Luci Stanescu | will be automatically generated |
117 | 39 | Luci Stanescu | |
118 | 1 | Adrian Georgescu | '''complete'''(''self'', '''full_remote_path'''):: |
119 | 39 | Luci Stanescu | This method establishes the connection to the relay and binds it (sends an empty chunk to verify each other's From-Path and To-Path). It returns {{{transport.MSRPTransport}}} instance, ready to read and send chunks. |
120 | 39 | Luci Stanescu | [[BR]]''full_remote_path'':[[BR]] |
121 | 39 | Luci Stanescu | A list of {{{protocol.URI}}} instances, obtained by parsing {{{'a:path'}}} put in SDP by the remote party. |
122 | 39 | Luci Stanescu | |
123 | 1 | Adrian Georgescu | '''cleanup'''(''self''):: |
124 | 39 | Luci Stanescu | This method cleans up after {{{prepare()}}}; it should be called if {{{complete()}}} will not be called for whatever reason. |
125 | 1 | Adrian Georgescu | |
126 | 48 | Luci Stanescu | == AcceptorDirect == |
127 | 1 | Adrian Georgescu | |
128 | 44 | Luci Stanescu | This class is implemented in the {{{msrplib.connect}}} module and is used for inbound MSRP connections without using a relay. |
129 | 1 | Adrian Georgescu | |
130 | 48 | Luci Stanescu | === Methods === |
131 | 39 | Luci Stanescu | |
132 | 39 | Luci Stanescu | '''!__init!__'''(''self'', '''loger'''={{{None}}}):: |
133 | 39 | Luci Stanescu | Constructs a new AcceptorDirect. |
134 | 39 | Luci Stanescu | [[BR]]''logger'':[[BR]] |
135 | 39 | Luci Stanescu | The logger which will be used for this MSRP connection. See the [wiki:SipMSRPApi#Logging Logging] section for more information. |
136 | 39 | Luci Stanescu | |
137 | 39 | Luci Stanescu | '''prepare'''(''self'', '''local_uri'''={{{None}}}):: |
138 | 1 | Adrian Georgescu | This method starts listening on a socket identified by the parameters in the {{{local_uri}}} argument. It returns a full local path - list of {{{protocol.URI}}} instances, suitable to be put in SDP {{{'a:path'}}} attribute. |
139 | 39 | Luci Stanescu | [[BR]]''local_uri'':[[BR]] |
140 | 39 | Luci Stanescu | This attribute will be used to construct the local path and to listen for incomming connections. If not provided, one |
141 | 1 | Adrian Georgescu | will be automatically generated |
142 | 39 | Luci Stanescu | |
143 | 39 | Luci Stanescu | '''complete'''(''self'', '''full_remote_path'''):: |
144 | 39 | Luci Stanescu | This method waits for an incoming connection and a chunk sent by the other party. It returns {{{transport.MSRPTransport}}} instance, ready to read and send chunks. |
145 | 39 | Luci Stanescu | [[BR]]''full_remote_path'':[[BR]] |
146 | 39 | Luci Stanescu | A list of {{{protocol.URI}}} instances, obtained by parsing {{{'a:path'}}} put in SDP by the remote party. This is checked agains the From-Path header in the binding chunk. |
147 | 39 | Luci Stanescu | |
148 | 39 | Luci Stanescu | '''cleanup'''(''self''):: |
149 | 39 | Luci Stanescu | This method cleans up after {{{prepare()}}}; it should be called if {{{complete()}}} will not be called for whatever reason. |
150 | 39 | Luci Stanescu | |
151 | 48 | Luci Stanescu | == AcceptorRelay == |
152 | 39 | Luci Stanescu | |
153 | 44 | Luci Stanescu | This class is implemented in the {{{msrplib.connect}}} module and is used for inbound MSRP connections using a relay. |
154 | 39 | Luci Stanescu | |
155 | 48 | Luci Stanescu | === Methods === |
156 | 39 | Luci Stanescu | |
157 | 39 | Luci Stanescu | '''!__init!__'''(''self'', '''relay''', '''loger'''={{{None}}}):: |
158 | 39 | Luci Stanescu | Constructs a new AcceptorRelay. |
159 | 39 | Luci Stanescu | [[BR]]''relay'':[[BR]] |
160 | 39 | Luci Stanescu | An instance of {{{MSRPRelaySettings}}} which identifies the relay which is to be used. |
161 | 39 | Luci Stanescu | [[BR]]''logger'':[[BR]] |
162 | 1 | Adrian Georgescu | The logger which will be used for this MSRP connection. See the [wiki:SipMSRPApi#Logging Logging] section for more information. |
163 | 39 | Luci Stanescu | |
164 | 39 | Luci Stanescu | '''prepare'''(''self'', '''local_uri'''={{{None}}}):: |
165 | 1 | Adrian Georgescu | This method connects to the relay specified in {{{__init__}}}. It returns a full local path - list of {{{protocol.URI}}} instances, suitable to be put in SDP {{{'a:path'}}} attribute. |
166 | 39 | Luci Stanescu | [[BR]]''local_uri'':[[BR]] |
167 | 39 | Luci Stanescu | This attribute will be used to construct the local path. If not provided, one will be automatically generated |
168 | 39 | Luci Stanescu | |
169 | 39 | Luci Stanescu | '''complete'''(''self'', '''full_remote_path'''):: |
170 | 39 | Luci Stanescu | This method waits for an incoming chunk sent by the other party. It returns {{{transport.MSRPTransport}}} instance, ready to read and send chunks. |
171 | 39 | Luci Stanescu | [[BR]]''full_remote_path'':[[BR]] |
172 | 39 | Luci Stanescu | A list of {{{protocol.URI}}} instances, obtained by parsing {{{'a:path'}}} put in SDP by the remote party. This is checked agains the From-Path header in the binding chunk. |
173 | 39 | Luci Stanescu | |
174 | 39 | Luci Stanescu | '''cleanup'''(''self''):: |
175 | 39 | Luci Stanescu | This method cleans up after {{{prepare()}}}; it should be called if {{{complete()}}} will not be called for whatever reason. |
176 | 39 | Luci Stanescu | |
177 | 48 | Luci Stanescu | == MSRPTransport == |
178 | 39 | Luci Stanescu | |
179 | 41 | Luci Stanescu | This class is implemented in the {{{msrplib.transport}}} module and provies low level access to the MSRP connection. This class should not be constructed directly, but rather its intances should be obtained by using the various connector/acceptor classes documented above |
180 | 39 | Luci Stanescu | |
181 | 48 | Luci Stanescu | === Methods === |
182 | 39 | Luci Stanescu | |
183 | 39 | Luci Stanescu | '''make_chunk'''(''self'', '''transaction_id'''={{{None}}}, '''method'''={{{'SEND'}}}, '''code'''={{{None}}}, '''comment'''={{{None}}}, '''data'''={{{''}}}, '''contflag'''={{{None}}}, '''start'''={{{1}}}, '''end'''={{{None}}}, '''length'''={{{None}}}, '''message_id'''={{{None}}}):: |
184 | 1 | Adrian Georgescu | Makes a new chunk ({{{protocol.MSRPData}}} instance) with proper {{{From-Path}}}, {{{To-Path}}}, {{{Byte-Range}}} and {{{Message-ID}}} headers set up based on MSRPTransport's state and the parameters provided. Use ''data'' for payload, and ''start''/''end''/''length'' to generate {{{Byte-Range}}} header. Generate new random strings for default values of ''transaction_id'' and ''message_id''. |
185 | 1 | Adrian Georgescu | [[BR]]''contflag'':[[BR]] |
186 | 1 | Adrian Georgescu | MSRP chunk's continuation flag ({{{'$'}}}, {{{'+'}}} or {{{'#'}}}). Default is {{{'$'}}}, unless you have a partial {{{SEND}}} chunk, in which case it is {{{'+'}}} |
187 | 14 | Oliver Bril | |
188 | 39 | Luci Stanescu | '''write'''(''self'', '''bytes''', '''sync'''={{{True}}}):: |
189 | 1 | Adrian Georgescu | Writes ''bytes'' to the socket. If ''sync'' is true, waits for an operation to complete. |
190 | 1 | Adrian Georgescu | |
191 | 39 | Luci Stanescu | '''read_chunk'''(''self'', '''size'''={{{None}}}):: |
192 | 1 | Adrian Georgescu | Waits for a new chunk and returns it. |
193 | 1 | Adrian Georgescu | If there was an error, closes the connection and raises {{{ChunkParseError}}}. |
194 | 1 | Adrian Georgescu | |
195 | 15 | Oliver Bril | In case of unintelligible input, loses the connection and returns {{{None}}}. |
196 | 1 | Adrian Georgescu | When the connection is closed, raises the reason of the closure (e.g. {{{ConnectionDone}}}). |
197 | 1 | Adrian Georgescu | |
198 | 27 | Adrian Georgescu | If the data already read exceeds ''size'', stops reading the data and returns |
199 | 38 | Adrian Georgescu | a "virtual" chunk, i.e. the one that does not actually correspond the the real |
200 | 1 | Adrian Georgescu | MSRP chunk. Such chunks have Byte-Range header changed to match the number of |
201 | 1 | Adrian Georgescu | bytes read and continuation that is {{{'+'}}}; they also possess {{{segment}}} attribute, |
202 | 1 | Adrian Georgescu | an integer, starting with 1 and increasing with every new segment of the chunk. |
203 | 15 | Oliver Bril | |
204 | 27 | Adrian Georgescu | Note, that ''size'' only hints when to interrupt the segment but does not affect |
205 | 1 | Adrian Georgescu | how the data is read from socket. You may have segments bigger than ''size'' and it's |
206 | 15 | Oliver Bril | legal to set ''size'' to zero (which would mean return a chunk as long as you get |
207 | 27 | Adrian Georgescu | some data, regardless how small). |
208 | 15 | Oliver Bril | |
209 | 39 | Luci Stanescu | '''check_incoming_SEND_chunk'''(''self'', '''chunk'''):: |
210 | 15 | Oliver Bril | Checks the 'To-Path' and 'From-Path' of the incoming SEND chunk. |
211 | 1 | Adrian Georgescu | Returns None is the paths are valid for this connection. |
212 | 15 | Oliver Bril | If an error is detected an MSRPError is created and returned. |
213 | 1 | Adrian Georgescu | |
214 | 48 | Luci Stanescu | == MSRPSession == |
215 | 15 | Oliver Bril | |
216 | 44 | Luci Stanescu | This class is implemented in the {{{msrplib.session}}} module and provides a high level API for MSRP sessions. |
217 | 39 | Luci Stanescu | |
218 | 48 | Luci Stanescu | === Methods === |
219 | 39 | Luci Stanescu | |
220 | 39 | Luci Stanescu | '''!__init!__'''(''self'', '''msrptransport''', '''accept_types'''={{{['*']}}}, '''on_incoming_cb'''={{{None}}}):: |
221 | 41 | Luci Stanescu | Initializes MSRPSession instance. The incoming chunks are reported through the ''on_incoming_cb'' callback, which must be a function which receives two arguments, both optional with default values of {{{None}}}: ''chunk'' and ''error''. |
222 | 1 | Adrian Georgescu | |
223 | 39 | Luci Stanescu | '''send_chunk'''(''self'', '''chunk''', '''response_cb'''={{{None}}}):: |
224 | 1 | Adrian Georgescu | Sends ''chunk''. Report the result via ''response_cb''. |
225 | 1 | Adrian Georgescu | |
226 | 1 | Adrian Georgescu | When ''response_cb'' argument is present, it will be used to report |
227 | 1 | Adrian Georgescu | the transaction response to the caller. When a response is received or generated |
228 | 1 | Adrian Georgescu | locally, ''response_cb'' is called with one argument. The function must do something |
229 | 1 | Adrian Georgescu | quickly and must not block, because otherwise it would block the reader greenlet. |
230 | 1 | Adrian Georgescu | |
231 | 1 | Adrian Georgescu | If no response was received after {{{RESPONSE_TIMEOUT}}} seconds, |
232 | 1 | Adrian Georgescu | * 408 response is generated if Failure-Report was {{{'yes'}}} or absent |
233 | 1 | Adrian Georgescu | * 200 response is generated if Failure-Report was {{{'partial'}}} or {{{'no'}}} |
234 | 1 | Adrian Georgescu | |
235 | 1 | Adrian Georgescu | Note that it's rather wasteful to provide ''response_cb'' argument other than {{{None}}} |
236 | 1 | Adrian Georgescu | for chunks with Failure-Report='no' since it will always fire 30 seconds later |
237 | 1 | Adrian Georgescu | with 200 result (unless the other party is broken and ignores Failure-Report header) |
238 | 1 | Adrian Georgescu | |
239 | 1 | Adrian Georgescu | If sending is impossible raise {{{MSRPSessionError}}}. |
240 | 38 | Adrian Georgescu | |
241 | 39 | Luci Stanescu | '''deliver_chunk'''(''self'', '''chunk''', '''event'''={{{None}}}):: |
242 | 1 | Adrian Georgescu | Sends the chunk, waits for the transaction response (if Failure-Report header is not {{{'no'}}}). |
243 | 1 | Adrian Georgescu | Returns the transaction response if it's a success, raise {{{MSRPTransactionError}}} if it's not. |
244 | 1 | Adrian Georgescu | |
245 | 1 | Adrian Georgescu | If chunk's Failure-Report is {{{'no'}}}, returns {{{None}}} immediately. |
246 | 1 | Adrian Georgescu | |
247 | 1 | Adrian Georgescu | '''shutdown'''(''self'', '''sync'''={{{True}}}):: |
248 | 41 | Luci Stanescu | Sends the messages already in queue then closes the connection. |
249 | 1 | Adrian Georgescu | |
250 | 48 | Luci Stanescu | == MSRPServer == |
251 | 38 | Adrian Georgescu | |
252 | 44 | Luci Stanescu | This class is implemented in the {{{msrplib.connect}}} module. |
253 | 1 | Adrian Georgescu | |
254 | 44 | Luci Stanescu | MSRPServer solves the problem with AcceptorDirect: concurrent using of 2 |
255 | 44 | Luci Stanescu | or more AcceptorDirect instances on the same non-zero port is not possible. |
256 | 44 | Luci Stanescu | If you initialize() those instances, one after another, one will listen on |
257 | 44 | Luci Stanescu | the socket and another will get BindError. |
258 | 1 | Adrian Georgescu | |
259 | 44 | Luci Stanescu | MSRPServer avoids the problem by sharing the listening socket between multiple connections. |
260 | 44 | Luci Stanescu | It has a slightly different interface from AcceptorDirect, so it cannot be considered a drop-in |
261 | 44 | Luci Stanescu | replacement. |
262 | 1 | Adrian Georgescu | |
263 | 44 | Luci Stanescu | It manages the listening sockets and binds incoming requests. |
264 | 39 | Luci Stanescu | |
265 | 39 | Luci Stanescu | |
266 | 48 | Luci Stanescu | === Methods === |
267 | 39 | Luci Stanescu | |
268 | 46 | Luci Stanescu | '''!__init!__'''(''self'', '''logger'''):: |
269 | 46 | Luci Stanescu | Constructs a new MSRPServer which will be using the specifed logger for its connections. See the [wiki:SipMSRPApi#Logging Logging] section for more information. |
270 | 46 | Luci Stanescu | |
271 | 1 | Adrian Georgescu | '''prepare'''(''self'', ''local_uri''={{{None}}}, ''logger''={{{None}}}):: |
272 | 1 | Adrian Georgescu | Starts a listening port specified by ''local_uri'' if there isn't one on that port/interface already. |
273 | 1 | Adrian Georgescu | Adds ''local_uri'' to the list of expected URIs, so that incoming connections featuring this URI won't be rejected. |
274 | 1 | Adrian Georgescu | If ''logger'' is provided, it uses it for this connection instead of the default one. |
275 | 1 | Adrian Georgescu | |
276 | 15 | Oliver Bril | '''complete'''(''self'', ''full_remote_path''):: |
277 | 1 | Adrian Georgescu | Waits until one of the incoming connections binds using provided ''full_remote_path''. |
278 | 15 | Oliver Bril | Returns connected and bounds the {{{MSRPTransport}}} instance. |
279 | 15 | Oliver Bril | |
280 | 15 | Oliver Bril | If no such binding was made within {{{MSRPBindSessionTimeout.seconds}}}, raise {{{MSRPBindSessionTimeout}}}. |
281 | 38 | Adrian Georgescu | ''full_remote_path'' should be a list of {{{protocol.URI}}} instances, obtained by parsing {{{'a:path'}}} put in SDP by the remote party. |
282 | 38 | Adrian Georgescu | |
283 | 38 | Adrian Georgescu | '''cleanup'''(''self'', ''local_uri''):: |
284 | 38 | Adrian Georgescu | Removes ''local_uri'' from the list of expected URIs. |
285 | 46 | Luci Stanescu | |
286 | 46 | Luci Stanescu | == Logging == |
287 | 46 | Luci Stanescu | |
288 | 46 | Luci Stanescu | Logging is done throughout the library using objects defined by the application, called loggers. If logging is not desired, the {{{application.python.Null}}} object of {{{python-application}}} can be used. These loggers must define the following methods: |
289 | 46 | Luci Stanescu | |
290 | 46 | Luci Stanescu | '''received_new_chunk'''('''data''', '''transport''', '''chunk'''):: |
291 | 46 | Luci Stanescu | This method is called when the start of a new chunk is received. |
292 | 46 | Luci Stanescu | [[BR]]''data'':[[BR]] |
293 | 46 | Luci Stanescu | The data which came along with the start of the chunk. |
294 | 46 | Luci Stanescu | [[BR]]''transport'':[[BR]] |
295 | 46 | Luci Stanescu | The {{{MSRPTransport}}} instance on which the chunk was received. |
296 | 46 | Luci Stanescu | [[BR]]''chunk'':[[BR]] |
297 | 46 | Luci Stanescu | The actual chunk object. |
298 | 46 | Luci Stanescu | |
299 | 46 | Luci Stanescu | '''received_chunk_data'''('''data''', '''transport''', '''transaction_id'''):: |
300 | 46 | Luci Stanescu | This method is called when data is received as part of a chunk previously announced via '''received_new_chunk'''. |
301 | 46 | Luci Stanescu | [[BR]]''data'':[[BR]] |
302 | 46 | Luci Stanescu | The data received as part of the chunk. |
303 | 46 | Luci Stanescu | [[BR]]''transport'':[[BR]] |
304 | 46 | Luci Stanescu | The {{{MSRPTransport}}} instance on which the chunk was received. |
305 | 46 | Luci Stanescu | [[BR]]''transaction_id'':[[BR]] |
306 | 46 | Luci Stanescu | The transaction ID which identifies the chunk for which data was received. |
307 | 46 | Luci Stanescu | |
308 | 47 | Luci Stanescu | '''received_chunk_end'''('''data''', '''transport''', '''transaction_id'''):: |
309 | 46 | Luci Stanescu | This method is called when the last data of a chunk is received. The chunk was previously announced via '''received_new_chunk'''. |
310 | 46 | Luci Stanescu | [[BR]]''data'':[[BR]] |
311 | 46 | Luci Stanescu | The last data received as part of the chunk. |
312 | 46 | Luci Stanescu | [[BR]]''transport'':[[BR]] |
313 | 46 | Luci Stanescu | The {{{MSRPTransport}}} instance on which the chunk was received. |
314 | 46 | Luci Stanescu | [[BR]]''transaction_id'':[[BR]] |
315 | 46 | Luci Stanescu | The transaction ID which identifies the chunk which was ended. |
316 | 46 | Luci Stanescu | |
317 | 46 | Luci Stanescu | '''sent_new_chunk'''('''data''', '''transport''', '''chunk'''):: |
318 | 46 | Luci Stanescu | This method is called when the start of a new chunk is sent. |
319 | 46 | Luci Stanescu | [[BR]]''data'':[[BR]] |
320 | 46 | Luci Stanescu | The data which was sent along with the start of the chunk. |
321 | 46 | Luci Stanescu | [[BR]]''transport'':[[BR]] |
322 | 46 | Luci Stanescu | The {{{MSRPTransport}}} instance on which the chunk was sent. |
323 | 46 | Luci Stanescu | [[BR]]''chunk'':[[BR]] |
324 | 46 | Luci Stanescu | The actual chunk object. |
325 | 46 | Luci Stanescu | |
326 | 46 | Luci Stanescu | '''sent_chunk_data'''('''data''', '''transport''', '''transaction_id'''):: |
327 | 46 | Luci Stanescu | This method is called when data is sent as part of a chunk previously announced via '''sent_new_chunk'''. |
328 | 46 | Luci Stanescu | [[BR]]''data'':[[BR]] |
329 | 46 | Luci Stanescu | The data sent as part of the chunk. |
330 | 46 | Luci Stanescu | [[BR]]''transport'':[[BR]] |
331 | 46 | Luci Stanescu | The {{{MSRPTransport}}} instance on which the chunk was sent. |
332 | 46 | Luci Stanescu | [[BR]]''transaction_id'':[[BR]] |
333 | 46 | Luci Stanescu | The transaction ID which identifies the chunk for which data was sent. |
334 | 46 | Luci Stanescu | |
335 | 47 | Luci Stanescu | '''sent_chunk_end'''('''data''', '''transport''', '''transaction_id'''):: |
336 | 46 | Luci Stanescu | This method is called when the last data of a chunk is sent. The chunk was previously announced via '''sent_new_chunk'''. |
337 | 46 | Luci Stanescu | [[BR]]''data'':[[BR]] |
338 | 46 | Luci Stanescu | The last data sent as part of the chunk. |
339 | 46 | Luci Stanescu | [[BR]]''transport'':[[BR]] |
340 | 46 | Luci Stanescu | The {{{MSRPTransport}}} instance on which the chunk was sent. |
341 | 46 | Luci Stanescu | [[BR]]''transaction_id'':[[BR]] |
342 | 46 | Luci Stanescu | The transaction ID which identifies the chunk which was ended. |
343 | 46 | Luci Stanescu | |
344 | 46 | Luci Stanescu | '''debug'''('''message'''):: |
345 | 46 | Luci Stanescu | This method is called when a debug level message is sent by the library. |
346 | 46 | Luci Stanescu | |
347 | 46 | Luci Stanescu | '''info'''('''message'''):: |
348 | 46 | Luci Stanescu | This method is called when a info level message is sent by the library. |
349 | 46 | Luci Stanescu | |
350 | 46 | Luci Stanescu | '''warn'''('''message'''):: |
351 | 46 | Luci Stanescu | This method is called when a warning level message is sent by the library. |
352 | 46 | Luci Stanescu | |
353 | 46 | Luci Stanescu | '''error'''('''message'''):: |
354 | 46 | Luci Stanescu | This method is called when a error level message is sent by the library. |
355 | 46 | Luci Stanescu | |
356 | 46 | Luci Stanescu | '''fatal'''('''message'''):: |
357 | 46 | Luci Stanescu | This method is called when a fatal level message is sent by the library. |
358 | 38 | Adrian Georgescu | |
359 | 39 | Luci Stanescu | == Example == |
360 | 38 | Adrian Georgescu | |
361 | 38 | Adrian Georgescu | === Establish a connection === |
362 | 38 | Adrian Georgescu | |
363 | 38 | Adrian Georgescu | {{{msrplib.connect}}} provides a number of classes to establish a connection, so the first |
364 | 38 | Adrian Georgescu | thing to do is to select which one applies to your situation: |
365 | 38 | Adrian Georgescu | |
366 | 38 | Adrian Georgescu | 1. Calling endpoint, not using a relay ({{{ConnectorDirect}}}) |
367 | 38 | Adrian Georgescu | 2. Answering endpoint, not using a relay ({{{AcceptorDirect}}}) |
368 | 38 | Adrian Georgescu | 3. Calling endpoint, using a relay ({{{ConnectorRelay}}}) |
369 | 38 | Adrian Georgescu | 4. Answering endpoint, using a relay ({{{AcceptorRelay}}}) |
370 | 38 | Adrian Georgescu | |
371 | 38 | Adrian Georgescu | The answering endpoint may skip using the relay if sure that it's accessible directly, e.g is not behind a NAT. To be sure it works in any network topology a called end-point should always use a relay. |
372 | 38 | Adrian Georgescu | |
373 | 38 | Adrian Georgescu | The calling endpoint does not need a relay as the protocol mandates that it is establishing an outbound connection which always work from behind a NAT. |
374 | 38 | Adrian Georgescu | |
375 | 38 | Adrian Georgescu | Once you have an instance of the right class (use the convenience functions |
376 | 38 | Adrian Georgescu | {{{get_connector()}}} and {{{get_acceptor()}}} to get one), the procedure to establish the |
377 | 38 | Adrian Georgescu | connection is the same: |
378 | 38 | Adrian Georgescu | |
379 | 38 | Adrian Georgescu | {{{ |
380 | 38 | Adrian Georgescu | full_local_path = connector.prepare() |
381 | 38 | Adrian Georgescu | try: |
382 | 38 | Adrian Georgescu | ... put full_local_path in SDP 'a:path' attribute |
383 | 38 | Adrian Georgescu | ... get full_remote_path from remote's 'a:path: attribute |
384 | 38 | Adrian Georgescu | ... (the order of the above steps is reversed if you're the |
385 | 38 | Adrian Georgescu | ... answering party, but that does not affect connector's usage) |
386 | 38 | Adrian Georgescu | msrptransport = connector.complete(full_remote_path) |
387 | 38 | Adrian Georgescu | finally: |
388 | 38 | Adrian Georgescu | connector.cleanup() |
389 | 38 | Adrian Georgescu | }}} |
390 | 38 | Adrian Georgescu | |
391 | 38 | Adrian Georgescu | To customize connection's parameters, creates a new {{{protocol.URI}}} object and passes |
392 | 38 | Adrian Georgescu | it to prepare() function, e.g. |
393 | 38 | Adrian Georgescu | {{{ |
394 | 38 | Adrian Georgescu | local_uri = protocol.URI(use_tls=False, port=5000) |
395 | 38 | Adrian Georgescu | connector.prepare(local_uri) |
396 | 38 | Adrian Georgescu | }}} |
397 | 38 | Adrian Georgescu | |
398 | 38 | Adrian Georgescu | {{{prepare()}}} may update {{{local_uri}}} in place with the actual connection parameters |
399 | 38 | Adrian Georgescu | used (e.g. if you specified port=0). 'port' attribute of {{{local_uri}}} is currently |
400 | 38 | Adrian Georgescu | only respected by {{{AcceptorDirect}}}. |
401 | 38 | Adrian Georgescu | |
402 | 1 | Adrian Georgescu | Note that, acceptors and connectors are one-use only. Which means, that {{{AcceptorDirect}}} |
403 | 1 | Adrian Georgescu | will open a port just to handle one incoming connection and close it right after. |
404 | 1 | Adrian Georgescu | If your application behaves more like a server, i.e. opens a port and listens on it |
405 | 1 | Adrian Georgescu | constantly, use {{{MSRPServer}}} class. |