SipMSRPApi » History » Version 5
Oliver Bril, 03/31/2009 12:46 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 | * 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 | |||
| 10 | 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: |
| 11 | 1 | Adrian Georgescu | |
| 12 | 4 | Oliver Bril | * {{{sipsimple.msrp.MSRPChat}}} |
| 13 | * {{{sipsimple.msrp.MSRPFileTransfer}}} |
||
| 14 | 1 | Adrian Georgescu | * {{{sipsimple.msrp.MSRPDesktopSharing}}} |
| 15 | |||
| 16 | 5 | Oliver Bril | Those 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. |
| 17 | Refer to [wiki:SipMiddlewareApi#Session Session documentation] for details on Session API. |
||
| 18 | |||
| 19 | 4 | Oliver Bril | == MSRPChat == |
| 20 | 1 | Adrian Georgescu | |
| 21 | 5 | Oliver Bril | {{{sipsimple.msrp.MSRPChat}}} implements Instance Messaging over MSRP in the context of SIPSIMPLE middleware. This class |
| 22 | 1 | Adrian Georgescu | |
| 23 | 5 | Oliver Bril | * automatically wraps outgoing messages with Message/CPIM if that's necessary according to accept-types |
| 24 | * unwraps incoming Message/CPIM messages |
||
| 25 | * plays notification sounds on received/sent message |
||
| 26 | |||
| 27 | === methods === |
||
| 28 | |||
| 29 | '''!__init!__'''(''self'', ''account'', ''remote_uri'', ''outgoing''):: |
||
| 30 | Initialize MSRPChat instance. |
||
| 31 | |||
| 32 | '''initialize'''(''self''):: |
||
| 33 | Initialize the MSRP connection; connect to the relay if necessary. When done, fire MSRPChatDidInitialize (with 'sdpmedia' attribute, containing the appropriate 'SDPMedia' instance) |
||
| 34 | |||
| 35 | '''start'''(''self'', ''remote_media''):: |
||
| 36 | Complete the MSRP connection establishment; this includes binding the MSRP session. [[BR]] |
||
| 37 | When done, fire MSRPChatDidStart. At this point each incoming message is posted as a {{{MSRPChatGotMessage}}} notification |
||
| 38 | |||
| 39 | '''end'''(''self''):: |
||
| 40 | Close the MSRP connection or cleanup after initialize(), whatever is necessary. [[BR]] |
||
| 41 | Before doing anything post {{{MSRPChatWillEnd}}}. |
||
| 42 | When done, post {{{MSRPChatDidEnd}}}. If there was an error, post {{{MSRPChatDidFail}}}. |
||
| 43 | {{{MSRPChatDidEnd}}} will be posted anyway. |
||
| 44 | |||
| 45 | |||
| 46 | === notifications === |
||
| 47 | |||
| 48 | '''MSRPChatGotMessage''': |
||
| 49 | Posted for each incoming message with the following attributes: |
||
| 50 | - cpim_headers (dict); if cpim wrapper was not used, empty dict |
||
| 51 | - message (MSRPData) |
||
| 52 | - content (str) - the actual string that the remote user has typed |
||
| 53 | |||
| 54 | 4 | Oliver Bril | == MSRPFileTransfer == |
| 55 | |||
| 56 | == MSRPDesktopSharing == |
||
| 57 | |||
| 58 | == msrplib == |
||
| 59 | |||
| 60 | 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 |
| 61 | classes for establishing and managing MSRP connection. |
||
| 62 | |||
| 63 | The library consist of the following modules: |
||
| 64 | |||
| 65 | '''msrplib.transport''':: |
||
| 66 | Defines {{{MSRPTransport}}} class, which provides low level control over MSRP connection. |
||
| 67 | 2 | Redmine Admin | |
| 68 | 1 | Adrian Georgescu | '''msrplib.connect''':: |
| 69 | Defines means to establish a connection, bind it, and provide an initialized {{{MSRPTransport}}} instance. |
||
| 70 | |||
| 71 | '''msrplib.session''':: |
||
| 72 | Defines {{{MSRPSession}}} class, which provides high level control over a MSRP connection. |
||
| 73 | |||
| 74 | '''msrplib.protocol''':: |
||
| 75 | Provides representation and parsing of MSRP entities - chunks and URIs. |
||
| 76 | |||
| 77 | '''msrplib.trafficlog''':: |
||
| 78 | Defines {{{Logger}}} class that is used through out the library to log the connection state. |
||
| 79 | |||
| 80 | 4 | Oliver Bril | === Usage === |
| 81 | 1 | Adrian Georgescu | |
| 82 | 4 | Oliver Bril | ==== Establish a connection ==== |
| 83 | 3 | Oliver Bril | |
| 84 | 1 | Adrian Georgescu | {{{msrplib.connect}}} provides a number of classes to establish a connection, so the first |
| 85 | thing to do is to select which one applies to your situation: |
||
| 86 | |||
| 87 | 1. Calling endpoint, not using a relay ({{{ConnectorDirect}}}) |
||
| 88 | 2. Answering endpoint, not using a relay ({{{AcceptorDirect}}}) |
||
| 89 | 3. Calling endpoint, using a relay ({{{ConnectorRelay}}}) |
||
| 90 | 4. Answering endpoint, using a relay ({{{AcceptorRelay}}}) |
||
| 91 | |||
| 92 | The answering endpoint may skip using the relay if sure that it's accessible |
||
| 93 | directly. The calling endpoint is unlikely to need the relay. |
||
| 94 | |||
| 95 | Once you have an instance of the right class (use the convenience functions |
||
| 96 | {{{get_connector()}}} and {{{get_acceptor()}}} to get one), the procedure to establish the |
||
| 97 | connection is the same: |
||
| 98 | |||
| 99 | {{{ |
||
| 100 | full_local_path = connector.prepare() |
||
| 101 | try: |
||
| 102 | ... put full_local_path in SDP 'a:path' attribute |
||
| 103 | ... get full_remote_path from remote's 'a:path: attribute |
||
| 104 | ... (the order of the above steps is reversed if you're the |
||
| 105 | ... answering party, but that does not affect connector's usage) |
||
| 106 | msrptransport = connector.complete(full_remote_path) |
||
| 107 | finally: |
||
| 108 | connector.cleanup() |
||
| 109 | }}} |
||
| 110 | |||
| 111 | To customize connection's parameters, create a new {{{protocol.URI}}} object and pass |
||
| 112 | it to prepare() function, e.g. |
||
| 113 | {{{ |
||
| 114 | local_uri = protocol.URI(use_tls=False, port=5000) |
||
| 115 | connector.prepare(local_uri) |
||
| 116 | }}} |
||
| 117 | |||
| 118 | {{{prepare()}}} may update {{{local_uri}}} in place with the actual connection parameters |
||
| 119 | used (e.g. if you specified port=0). 'port' attribute of {{{local_uri}}} is currently |
||
| 120 | only respected by {{{AcceptorDirect}}}. |
||
| 121 | |||
| 122 | Note that, acceptors and connectors are one-use only. Which means, that {{{AcceptorDirect}}} |
||
| 123 | will open a port just to handle one incoming connection and close it right after. |
||
| 124 | If your application behaves more like a server, i.e. opens a port and listens on it |
||
| 125 | constantly, use {{{MSRPServer}}} class. |
||
| 126 | 3 | Oliver Bril | |
| 127 | 4 | Oliver Bril | === Components === |
| 128 | 1 | Adrian Georgescu | |
| 129 | 4 | Oliver Bril | ==== a connector or acceptor ==== |
| 130 | 3 | Oliver Bril | |
| 131 | 4 | Oliver Bril | ===== attributes ===== |
| 132 | ===== methods ===== |
||
| 133 | 1 | Adrian Georgescu | |
| 134 | 4 | Oliver Bril | ==== transport.MSRPTransport ==== |
| 135 | 1 | Adrian Georgescu | |
| 136 | Low level access to MSRP connection. |
||
| 137 | |||
| 138 | 4 | Oliver Bril | ===== attributes ===== |
| 139 | 3 | Oliver Bril | |
| 140 | 4 | Oliver Bril | ===== methods ===== |
| 141 | 3 | Oliver Bril | |
| 142 | '''make_chunk'''(''self'', ''transaction_id''={{{None}}}, ''method''={{{'SEND'}}}, ''code''={{{None}}}, ''comment''={{{None}}}, ''data''={{{''}}}, ''contflag''={{{None}}}, ''start''={{{1}}}, ''end''={{{None}}}, ''length''={{{None}}}, ''message_id''={{{None}}}):: |
||
| 143 | 1 | Adrian Georgescu | Make 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''. |
| 144 | [[BR]]''contflag'':[[BR]] |
||
| 145 | MSRP chunk's continuation flag ({{{'$'}}}, {{{'+'}}} or {{{'#'}}}). Default is {{{'$'}}}, unless you have a partial {{{SEND}}} chunk, in which case it is {{{'+'}}} |
||
| 146 | |||
| 147 | 4 | Oliver Bril | ==== session.MSRPSession ==== |
| 148 | ===== attributes ===== |
||
| 149 | ===== methods ===== |
||
| 150 | 1 | Adrian Georgescu | |
| 151 | 4 | Oliver Bril | ==== connect.MSRPServer ==== |
| 152 | ===== attributes ===== |
||
| 153 | ===== methods ===== |