SipMSRPApi » History » Version 28
Adrian Georgescu, 03/31/2009 05:48 PM
| 1 | 1 | Adrian Georgescu | = MSRP API = |
|---|---|---|---|
| 2 | |||
| 3 | [[TOC(WikiStart, Sip*, depth=3)]] |
||
| 4 | |||
| 5 | 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 | |||
| 7 | 25 | Adrian Georgescu | * MSRP sessions are defined in [http://tools.ietf.org/html/rfc4975 RFC 4975] |
| 8 | * 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 | 26 | Adrian Georgescu | * Common Presence and Instant Messaging (CPIM): Message Format is defined in [http://tools.ietf.org/html/rfc3862 RFC 3862] |
| 10 | 1 | Adrian Georgescu | |
| 11 | 5 | Oliver Bril | The MSRP protocol is implemented by [http://devel.ag-projects.com/cgi-bin/darcsweb.cgi?r=python-msrplib;a=summary msrplib] Python package. On top of it, {{{sipsimple}}} provides higher level classes integrated into middleware notification and configuration systems: |
| 12 | 1 | Adrian Georgescu | |
| 13 | 4 | Oliver Bril | * {{{sipsimple.msrp.MSRPChat}}} |
| 14 | * {{{sipsimple.msrp.MSRPFileTransfer}}} |
||
| 15 | 1 | Adrian Georgescu | * {{{sipsimple.msrp.MSRPDesktopSharing}}} |
| 16 | |||
| 17 | 21 | Adrian Georgescu | These classes are used internally by [wiki:SipMiddlewareApi#Session Session], which provides the necessary methods to access their features. The notifications posted by these classes are also handled internally by [wiki:SipMiddlewareApi#Session Session]. The notifications that are relevant to the user are then reposted by the Session instance. Refer to [wiki:SipMiddlewareApi#Session Session documentation] for details on the Session API. |
| 18 | 10 | Adrian Georgescu | |
| 19 | 23 | Adrian Georgescu | == MSRPChat API == |
| 20 | 1 | Adrian Georgescu | |
| 21 | 20 | Adrian Georgescu | {{{sipsimple.msrp.MSRPChat}}} implements instant messaging (IM) over MSRP for the [wiki:SipMiddlewareApi middleware]. This class performs the following functions: |
| 22 | 1 | Adrian Georgescu | |
| 23 | 5 | Oliver Bril | * automatically wraps outgoing messages with Message/CPIM if that's necessary according to accept-types |
| 24 | 19 | Adrian Georgescu | * unwraps incoming Message/CPIM messages; for each incoming message, {{{MSRPChatGotMessage}}} is posted |
| 25 | 5 | Oliver Bril | * plays notification sounds on received/sent message |
| 26 | |||
| 27 | 17 | Oliver Bril | === Methods === |
| 28 | 5 | Oliver Bril | |
| 29 | '''!__init!__'''(''self'', ''account'', ''remote_uri'', ''outgoing''):: |
||
| 30 | 27 | Adrian Georgescu | Initializes the MSRPChat instance. |
| 31 | 5 | Oliver Bril | |
| 32 | '''initialize'''(''self''):: |
||
| 33 | 27 | Adrian Georgescu | Initializes the MSRP connection; connects to the relay if necessary. When done, fires MSRPChatDidInitialize (with 'sdpmedia' attribute, containing the appropriate 'SDPMedia' instance) |
| 34 | 5 | Oliver Bril | |
| 35 | '''start'''(''self'', ''remote_media''):: |
||
| 36 | 27 | Adrian Georgescu | Completes the MSRP connection establishment; this includes binding the MSRP session. [[BR]] |
| 37 | When done, fires MSRPChatDidStart notification. At this point each incoming message is posted as a {{{MSRPChatGotMessage}}} notification |
||
| 38 | 5 | Oliver Bril | |
| 39 | '''end'''(''self''):: |
||
| 40 | 27 | Adrian Georgescu | Closes the MSRP connection or cleans up after initialize(), whatever is necessary. [[BR]] |
| 41 | Before doing anything posts {{{MSRPChatWillEnd}}} notification. |
||
| 42 | When done, posts {{{MSRPChatDidEnd}}} notification. If there was an error, posts {{{MSRPChatDidFail}}} notification. |
||
| 43 | {{{MSRPChatDidEnd}}} notification will be posted anyway. |
||
| 44 | 5 | Oliver Bril | |
| 45 | 6 | Oliver Bril | '''send_message'''(''self'', ''content'', ''content_type''={{{'text/plain'}}}, ''to_uri''={{{None}}}, ''dt''={{{None}}}):: |
| 46 | 27 | Adrian Georgescu | Sends IM message. Prefer Message/CPIM wrapper if it is supported. If called before the connection was established, the messages will be |
| 47 | 6 | Oliver Bril | queued until MSRPChatDidStart notification. |
| 48 | |||
| 49 | 27 | Adrian Georgescu | Returns the generated MSRP chunk (MSRPData instance); to get Message-ID use its 'message_id' attribute. |
| 50 | 6 | Oliver Bril | |
| 51 | ''content'' str:[[BR]] |
||
| 52 | content of the message |
||
| 53 | |||
| 54 | ''to_uri'' SIPURI:[[BR]] |
||
| 55 | "To" header of CPIM wrapper; use to override the default supplied to {{{__init__}}}. |
||
| 56 | May only differ from the one supplied in __init__ if the remote party supports private messages. If it does not, {{{MSRPChatError}}} will be raised; |
||
| 57 | |||
| 58 | ''content_type'' str:[[BR]] |
||
| 59 | Content-Type of wrapped message if Message/CPIM is used (Content-Type of MSRP message is always Message/CPIM in that case); |
||
| 60 | otherwise, Content-Type of MSRP message. |
||
| 61 | |||
| 62 | These MSRP headers are used to enable end-to-end success reports and to disable hop-to-hop successful responses: |
||
| 63 | {{{ |
||
| 64 | Failure-Report: partial |
||
| 65 | Success-Report: yes |
||
| 66 | }}} |
||
| 67 | |||
| 68 | 1 | Adrian Georgescu | === Notifications === |
| 69 | 21 | Adrian Georgescu | |
| 70 | To communicate with the middleware, MSRPChat class uses the notification system provided by the [http://pypi.python.org/pypi/python-application python-application] package. |
||
| 71 | 1 | Adrian Georgescu | |
| 72 | 17 | Oliver Bril | '''MSRPChatDidInitialize''':: |
| 73 | 18 | Adrian Georgescu | Sent when the {{{MSRPChat}}} instance is initialized, it includes the MSRP relay reservation when requested. |
| 74 | 17 | Oliver Bril | '''MSRPChatDidStart''':: |
| 75 | Sent when the {{{MSRPChat}}} instance is started. |
||
| 76 | '''MSRPChatWillEnd''':: |
||
| 77 | Sent when the {{{MSRPChat}}} is entering cleanup procedure initiated by calling end(). |
||
| 78 | '''MSRPChatDidEnd''':: |
||
| 79 | Sent when the {{{MSRPChat}}} has finished the cleanup procedure initiated by end(). |
||
| 80 | '''MSRPChatDidFail''':: |
||
| 81 | Sent whenever the {{{MSRPChat}}} instance fails. |
||
| 82 | [[BR]]''context'':[[BR]] |
||
| 83 | A text string identifying the context of the failure ('initialize', 'sdp_negotiation', 'start', 'reading'). |
||
| 84 | [[BR]]''reason'':[[BR]] |
||
| 85 | A text string describing the reason of failure. |
||
| 86 | [[BR]]''failure'':[[BR]] |
||
| 87 | A Failure instance providing detailed traceback information. |
||
| 88 | '''MSRPChatGotMessage''':: |
||
| 89 | Sent whenever a new incoming message is received, |
||
| 90 | [[BR]]''content'':[[BR]] |
||
| 91 | The string that the remote user has typed. |
||
| 92 | [[BR]]''content_type'':[[BR]] |
||
| 93 | Content-Type of the user message. |
||
| 94 | [[BR]]''cpim_headers'':[[BR]] |
||
| 95 | A dictionary of CPIM headers. (Empty dictionary if no CPIM wrapper was used). |
||
| 96 | [[BR]]''message'':[[BR]] |
||
| 97 | A {{{msrplib.protocol.MSRPData}}} instance providing all the MSRP information about the chunk. |
||
| 98 | '''MSRPChatDidDeliverMessage''':: |
||
| 99 | Sent when a successful report is received. |
||
| 100 | [[BR]]''message_id'':[[BR]] |
||
| 101 | Text identifier of the message. |
||
| 102 | [[BR]]''code'':[[BR]] |
||
| 103 | Integer result code. |
||
| 104 | [[BR]]''reason'':[[BR]] |
||
| 105 | Text comment. |
||
| 106 | [[BR]]''message'':[[BR]] |
||
| 107 | A {{{msrplib.protocol.MSRPData}}} instance providing all the MSRP information about the report. |
||
| 108 | '''MSRPChatDidNotDeliverMessage''':: |
||
| 109 | Sent when a failure report of failure transaction response is received. |
||
| 110 | [[BR]]''message_id'':[[BR]] |
||
| 111 | Text identifier of the message. |
||
| 112 | [[BR]]''code'':[[BR]] |
||
| 113 | Integer result code. |
||
| 114 | [[BR]]''reason'':[[BR]] |
||
| 115 | Text comment. |
||
| 116 | [[BR]]''message'':[[BR]] |
||
| 117 | A {{{msrplib.protocol.MSRPData}}} instance providing all the MSRP information about the report. |
||
| 118 | 5 | Oliver Bril | |
| 119 | 4 | Oliver Bril | == MSRPFileTransfer == |
| 120 | 1 | Adrian Georgescu | |
| 121 | 22 | Adrian Georgescu | === Methods === |
| 122 | === Notifications === |
||
| 123 | |||
| 124 | 1 | Adrian Georgescu | == MSRPDesktopSharing == |
| 125 | 22 | Adrian Georgescu | |
| 126 | === Methods === |
||
| 127 | === Notifications === |
||
| 128 | 1 | Adrian Georgescu | |
| 129 | 12 | Adrian Georgescu | ---------------------- |
| 130 | |||
| 131 | 24 | Adrian Georgescu | == MSRP library == |
| 132 | 4 | Oliver Bril | |
| 133 | 1 | Adrian Georgescu | {{{msrplib}}} is based upon [http://twistedmatrix.com twisted] and [http://devel.ag-projects.com/~denis/eventlet/ eventlet] and provides a set of |
| 134 | 27 | Adrian Georgescu | classes for establishing and managing MSRP connections. |
| 135 | 1 | Adrian Georgescu | |
| 136 | 28 | Adrian Georgescu | The library consists of the following modules: |
| 137 | 1 | Adrian Georgescu | |
| 138 | '''msrplib.transport''':: |
||
| 139 | 27 | Adrian Georgescu | Defines {{{MSRPTransport}}} class, which provides low level control over MSRP connections. |
| 140 | 2 | Redmine Admin | |
| 141 | 1 | Adrian Georgescu | '''msrplib.connect''':: |
| 142 | Defines means to establish a connection, bind it, and provide an initialized {{{MSRPTransport}}} instance. |
||
| 143 | |||
| 144 | '''msrplib.session''':: |
||
| 145 | Defines {{{MSRPSession}}} class, which provides high level control over a MSRP connection. |
||
| 146 | |||
| 147 | '''msrplib.protocol''':: |
||
| 148 | 27 | Adrian Georgescu | Provides representation and parsing of MSRP entities - chunks and MSRP URIs. |
| 149 | 1 | Adrian Georgescu | |
| 150 | '''msrplib.trafficlog''':: |
||
| 151 | Defines {{{Logger}}} class that is used through out the library to log the connection state. |
||
| 152 | |||
| 153 | === Usage === |
||
| 154 | 4 | Oliver Bril | |
| 155 | 1 | Adrian Georgescu | ==== Establish a connection ==== |
| 156 | 4 | Oliver Bril | |
| 157 | 3 | Oliver Bril | {{{msrplib.connect}}} provides a number of classes to establish a connection, so the first |
| 158 | 1 | Adrian Georgescu | thing to do is to select which one applies to your situation: |
| 159 | |||
| 160 | 1. Calling endpoint, not using a relay ({{{ConnectorDirect}}}) |
||
| 161 | 2. Answering endpoint, not using a relay ({{{AcceptorDirect}}}) |
||
| 162 | 3. Calling endpoint, using a relay ({{{ConnectorRelay}}}) |
||
| 163 | 4. Answering endpoint, using a relay ({{{AcceptorRelay}}}) |
||
| 164 | |||
| 165 | 27 | 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. |
| 166 | 1 | Adrian Georgescu | |
| 167 | 27 | 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. |
| 168 | |||
| 169 | 1 | Adrian Georgescu | Once you have an instance of the right class (use the convenience functions |
| 170 | {{{get_connector()}}} and {{{get_acceptor()}}} to get one), the procedure to establish the |
||
| 171 | connection is the same: |
||
| 172 | |||
| 173 | {{{ |
||
| 174 | full_local_path = connector.prepare() |
||
| 175 | try: |
||
| 176 | ... put full_local_path in SDP 'a:path' attribute |
||
| 177 | ... get full_remote_path from remote's 'a:path: attribute |
||
| 178 | ... (the order of the above steps is reversed if you're the |
||
| 179 | ... answering party, but that does not affect connector's usage) |
||
| 180 | msrptransport = connector.complete(full_remote_path) |
||
| 181 | finally: |
||
| 182 | connector.cleanup() |
||
| 183 | }}} |
||
| 184 | |||
| 185 | 27 | Adrian Georgescu | To customize connection's parameters, creates a new {{{protocol.URI}}} object and passes |
| 186 | 1 | Adrian Georgescu | it to prepare() function, e.g. |
| 187 | {{{ |
||
| 188 | local_uri = protocol.URI(use_tls=False, port=5000) |
||
| 189 | connector.prepare(local_uri) |
||
| 190 | }}} |
||
| 191 | |||
| 192 | {{{prepare()}}} may update {{{local_uri}}} in place with the actual connection parameters |
||
| 193 | used (e.g. if you specified port=0). 'port' attribute of {{{local_uri}}} is currently |
||
| 194 | only respected by {{{AcceptorDirect}}}. |
||
| 195 | |||
| 196 | Note that, acceptors and connectors are one-use only. Which means, that {{{AcceptorDirect}}} |
||
| 197 | will open a port just to handle one incoming connection and close it right after. |
||
| 198 | If your application behaves more like a server, i.e. opens a port and listens on it |
||
| 199 | constantly, use {{{MSRPServer}}} class. |
||
| 200 | 3 | Oliver Bril | |
| 201 | 1 | Adrian Georgescu | === Components === |
| 202 | |||
| 203 | 4 | Oliver Bril | ==== a connector or acceptor ==== |
| 204 | 3 | Oliver Bril | |
| 205 | 8 | Oliver Bril | {{{msrplib.connect}}} provides 2 connectors (with and without relay) and 2 acceptors (likewise, with or without relay). All of them have the exact same interface, |
| 206 | |||
| 207 | 1 | Adrian Georgescu | '''prepare'''(''self'', ''local_uri''={{{None}}}):: |
| 208 | 8 | Oliver Bril | Depending on type of the connector, use local_uri to prepare the MSRP connection, which means: |
| 209 | * connecting and authenticating at the relay if a relay is used ({{{ConnectorRelay}}} and {{{AcceptorRelay}}}) |
||
| 210 | 27 | Adrian Georgescu | * starts listening on a local port for DirectAcceptor |
| 211 | 1 | Adrian Georgescu | |
| 212 | 8 | Oliver Bril | ''local_uri'' is used to specify the connection parameters, e.g. local port and local ip. |
| 213 | 1 | Adrian Georgescu | If not provided, suitable ''local_uri'' will be generated. |
| 214 | 8 | Oliver Bril | ''local_uri'' maybe updated in place by {{{prepare()}}} method if the real settings used are different from those specified. |
| 215 | |||
| 216 | {{{prepare}}} returns a full local path - list of {{{protocol.URI}}} instances, suitable to be put in SDP {{{'a:path'}}} attribute. |
||
| 217 | 1 | Adrian Georgescu | |
| 218 | 8 | Oliver Bril | '''complete'''(''self'', ''full_remote_path''):: |
| 219 | 27 | Adrian Georgescu | Completes the establishment of the MSRP connection, which means: |
| 220 | * establishes the connection if it wasn't already established ({{{ConnectorDirect}}}) |
||
| 221 | * binds the connection, i.e. exchanges empty chunk to verify each other's From-Path and To-Path |
||
| 222 | 8 | Oliver Bril | |
| 223 | ''full_remote_path'' should be a list of {{{protocol.URI}}} instances, obtained by parsing {{{'a:path'}}} put in SDP by the remote party. |
||
| 224 | |||
| 225 | {{{complete}}} returns {{{transport.MSRPTransport}}} instance, ready to read and send chunks. |
||
| 226 | 9 | Oliver Bril | |
| 227 | '''cleanup'''(''self''):: |
||
| 228 | 27 | Adrian Georgescu | Calls this method to cleanup after {{{initialize()}}} if it's impossible to call {{{complete()}}} |
| 229 | 8 | Oliver Bril | |
| 230 | 1 | Adrian Georgescu | |
| 231 | 4 | Oliver Bril | ==== transport.MSRPTransport ==== |
| 232 | 1 | Adrian Georgescu | |
| 233 | 27 | Adrian Georgescu | Low level access to the MSRP connection. |
| 234 | 1 | Adrian Georgescu | |
| 235 | '''make_chunk'''(''self'', ''transaction_id''={{{None}}}, ''method''={{{'SEND'}}}, ''code''={{{None}}}, ''comment''={{{None}}}, ''data''={{{''}}}, ''contflag''={{{None}}}, ''start''={{{1}}}, ''end''={{{None}}}, ''length''={{{None}}}, ''message_id''={{{None}}}):: |
||
| 236 | 27 | 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''. |
| 237 | 1 | Adrian Georgescu | [[BR]]''contflag'':[[BR]] |
| 238 | MSRP chunk's continuation flag ({{{'$'}}}, {{{'+'}}} or {{{'#'}}}). Default is {{{'$'}}}, unless you have a partial {{{SEND}}} chunk, in which case it is {{{'+'}}} |
||
| 239 | |||
| 240 | 14 | Oliver Bril | '''write'''(''self'', ''bytes'', ''sync''={{{True}}}):: |
| 241 | 27 | Adrian Georgescu | Writes ''bytes'' to the socket. If ''sync'' is true, waits for an operation to complete. |
| 242 | 14 | Oliver Bril | |
| 243 | '''read_chunk'''(''self'', ''size''={{{None}}}):: |
||
| 244 | 27 | Adrian Georgescu | Waits for a new chunk and returns it. |
| 245 | If there was an error, closes the connection and raises {{{ChunkParseError}}}. |
||
| 246 | 14 | Oliver Bril | |
| 247 | 27 | Adrian Georgescu | In case of unintelligible input, loses the connection and returns {{{None}}}. |
| 248 | When the connection is closed, raises the reason of the closure (e.g. {{{ConnectionDone}}}). |
||
| 249 | 14 | Oliver Bril | |
| 250 | 27 | Adrian Georgescu | If the data already read exceeds ''size'', stops reading the data and returns |
| 251 | 14 | Oliver Bril | a "virtual" chunk, i.e. the one that does not actually correspond the the real |
| 252 | MSRP chunk. Such chunks have Byte-Range header changed to match the number of |
||
| 253 | bytes read and continuation that is {{{'+'}}}; they also possess {{{segment}}} attribute, |
||
| 254 | an integer, starting with 1 and increasing with every new segment of the chunk. |
||
| 255 | |||
| 256 | 1 | Adrian Georgescu | Note, that ''size'' only hints when to interrupt the segment but does not affect |
| 257 | how the data is read from socket. You may have segments bigger than ''size'' and it's |
||
| 258 | 14 | Oliver Bril | legal to set ''size'' to zero (which would mean return a chunk as long as you get |
| 259 | 1 | Adrian Georgescu | some data, regardless how small). |
| 260 | |||
| 261 | 15 | Oliver Bril | '''check_incoming_SEND_chunk'''(''self'', ''chunk''):: |
| 262 | 27 | Adrian Georgescu | Checks the 'To-Path' and 'From-Path' of the incoming SEND chunk. |
| 263 | Returns None is the paths are valid for this connection. |
||
| 264 | 15 | Oliver Bril | If an error is detected an MSRPError is created and returned. |
| 265 | 1 | Adrian Georgescu | |
| 266 | 4 | Oliver Bril | ==== session.MSRPSession ==== |
| 267 | 1 | Adrian Georgescu | |
| 268 | 15 | Oliver Bril | '''!__init!__'''(''self'', ''msrptransport'', ''accept_types''={{{['*']}}}, ''on_incoming_cb''={{{None}}}):: |
| 269 | 27 | Adrian Georgescu | Initializes MSRPSession instance. Reports the incoming chunks through ''on_incoming_cb'' callback. |
| 270 | 1 | Adrian Georgescu | |
| 271 | 15 | Oliver Bril | '''send_chunk'''(''self'', ''chunk'', ''response_cb''={{{None}}}):: |
| 272 | 27 | Adrian Georgescu | Sends ''chunk''. Report the result via ''response_cb''. |
| 273 | 15 | Oliver Bril | |
| 274 | When ''response_cb'' argument is present, it will be used to report |
||
| 275 | the transaction response to the caller. When a response is received or generated |
||
| 276 | locally, ''response_cb'' is called with one argument. The function must do something |
||
| 277 | quickly and must not block, because otherwise it would the reader greenlet. |
||
| 278 | |||
| 279 | If no response was received after {{{RESPONSE_TIMEOUT}}} seconds, |
||
| 280 | * 408 response is generated if Failure-Report was {{{'yes'}}} or absent |
||
| 281 | 1 | Adrian Georgescu | * 200 response is generated if Failure-Report was {{{'partial'}}} or {{{'no'}}} |
| 282 | 15 | Oliver Bril | |
| 283 | 1 | Adrian Georgescu | Note that it's rather wasteful to provide ''response_cb'' argument other than {{{None}}} |
| 284 | 15 | Oliver Bril | for chunks with Failure-Report='no' since it will always fire 30 seconds later |
| 285 | with 200 result (unless the other party is broken and ignores Failure-Report header) |
||
| 286 | |||
| 287 | 16 | Oliver Bril | If sending is impossible raise {{{MSRPSessionError}}}. |
| 288 | 1 | Adrian Georgescu | |
| 289 | 16 | Oliver Bril | '''deliver_chunk'''(''self'', ''chunk'', ''event''={{{None}}}):: |
| 290 | 27 | Adrian Georgescu | Sends the chunk, waits for the transaction response (if Failure-Report header is not {{{'no'}}}). |
| 291 | Returns the transaction response if it's a success, raise {{{MSRPTransactionError}}} if it's not. |
||
| 292 | 16 | Oliver Bril | |
| 293 | 27 | Adrian Georgescu | If chunk's Failure-Report is {{{'no'}}}, returns {{{None}}} immediately. |
| 294 | 16 | Oliver Bril | |
| 295 | '''shutdown'''(''self'', ''sync''={{{True}}}):: |
||
| 296 | 27 | Adrian Georgescu | Sends the messages already in queue then close the connection. |
| 297 | 16 | Oliver Bril | |
| 298 | ==== session.GreenMSRPSession ==== |
||
| 299 | |||
| 300 | A subclass of MSRPSession that delivers the incoming messages to the queue. |
||
| 301 | |||
| 302 | '''!__init!__'''(''self'', ''msrptransport'', ''accept_types''={{{['*']}}}):: |
||
| 303 | 27 | Adrian Georgescu | Initializes GreenMSRPSession instance. The messages will be delivered to the queue (available as {{{incoming}}} attribute). |
| 304 | 16 | Oliver Bril | |
| 305 | '''receive_chunk'''(''self''):: |
||
| 306 | 27 | Adrian Georgescu | Returns a message from the queue. |
| 307 | 16 | Oliver Bril | |
| 308 | 1 | Adrian Georgescu | |
| 309 | 4 | Oliver Bril | ==== connect.MSRPServer ==== |
| 310 | 27 | Adrian Georgescu | Manages the listening sockets. Binds incoming requests. |
| 311 | 13 | Oliver Bril | |
| 312 | MSRPServer solves the problem with AcceptorDirect: concurrent using of 2 |
||
| 313 | or more AcceptorDirect instances on the same non-zero port is not possible. |
||
| 314 | If you initialize() those instances, one after another, one will listen on |
||
| 315 | the socket and another will get BindError. |
||
| 316 | |||
| 317 | MSRPServer avoids the problem by sharing the listening socket between multiple connections. |
||
| 318 | It has a slightly different interface from AcceptorDirect, so it cannot be considered a drop-in |
||
| 319 | replacement. |
||
| 320 | |||
| 321 | '''prepare'''(''self'', ''local_uri''={{{None}}}, ''logger''={{{None}}}):: |
||
| 322 | 27 | Adrian Georgescu | Starts a listening port specified by ''local_uri'' if there isn't one on that port/interface already. |
| 323 | Adds ''local_uri'' to the list of expected URIs, so that incoming connections featuring this URI won't be rejected. |
||
| 324 | If ''logger'' is provided, it uses it for this connection instead of the default one. |
||
| 325 | 13 | Oliver Bril | |
| 326 | '''complete'''(''self'', ''full_remote_path''):: |
||
| 327 | 27 | Adrian Georgescu | Waits until one of the incoming connections binds using provided ''full_remote_path''. |
| 328 | Returns connected and bounds the {{{MSRPTransport}}} instance. |
||
| 329 | 13 | Oliver Bril | |
| 330 | If no such binding was made within {{{MSRPBindSessionTimeout.seconds}}}, raise {{{MSRPBindSessionTimeout}}}. |
||
| 331 | ''full_remote_path'' should be a list of {{{protocol.URI}}} instances, obtained by parsing {{{'a:path'}}} put in SDP by the remote party. |
||
| 332 | |||
| 333 | '''cleanup'''(''self'', ''local_uri''):: |
||
| 334 | 27 | Adrian Georgescu | Removes ''local_uri'' from the list of expected URIs. |