ODF
Version 10 (Adrian Georgescu, 11/04/2014 01:25 pm)
1 | 1 | Adrian Georgescu | h1. ODF integration |
---|---|---|---|
2 | 1 | Adrian Georgescu | |
3 | 5 | Adrian Georgescu | This documents layout the changes required to support a new type of stream for collaborative editing. |
4 | 1 | Adrian Georgescu | |
5 | 6 | Adrian Georgescu | h2. SDK changes |
6 | 1 | Adrian Georgescu | |
7 | 6 | Adrian Georgescu | h3. Signaling |
8 | 6 | Adrian Georgescu | |
9 | 1 | Adrian Georgescu | There is no need to alter anything related to signalling. |
10 | 1 | Adrian Georgescu | |
11 | 6 | Adrian Georgescu | h3. Media |
12 | 1 | Adrian Georgescu | |
13 | 7 | Adrian Georgescu | h4. Variant 1 |
14 | 7 | Adrian Georgescu | |
15 | 10 | Adrian Georgescu | This by far the simplest way. Establish a standard chat stream and add _'application/odf+xml'_ to the lists of supported payloads by subclassing the standard Chat stream from the SDK. |
16 | 8 | Adrian Georgescu | |
17 | 1 | Adrian Georgescu | <pre> |
18 | 10 | Adrian Georgescu | class ODFChatStream(ChatStream): |
19 | 10 | Adrian Georgescu | accept_types = ['message/cpim', 'text/*', 'application/im-iscomposing+xml', 'application/odf+xml'] |
20 | 10 | Adrian Georgescu | </pre> |
21 | 10 | Adrian Georgescu | |
22 | 10 | Adrian Georgescu | Then during the session send the data using: |
23 | 10 | Adrian Georgescu | |
24 | 10 | Adrian Georgescu | <pre> |
25 | 10 | Adrian Georgescu | self.stream.send_message(data, content_type='application/odf+xml', timestamp=ISOTimestamp.now()) |
26 | 10 | Adrian Georgescu | </pre> |
27 | 10 | Adrian Georgescu | |
28 | 10 | Adrian Georgescu | Optionally add an attribute to the MSRP stream to signal the support for this feature: |
29 | 10 | Adrian Georgescu | |
30 | 10 | Adrian Georgescu | <pre> |
31 | 10 | Adrian Georgescu | class ODFChatStream(ChatStream): |
32 | 10 | Adrian Georgescu | accept_types = ['message/cpim', 'text/*', 'application/im-iscomposing+xml', 'application/odf+xml'] |
33 | 8 | Adrian Georgescu | def _create_local_media(self, uri_path): |
34 | 1 | Adrian Georgescu | local_media = super(BlinkChatStream, self)._create_local_media(uri_path) |
35 | 10 | Adrian Georgescu | local_media.attributes.append(SDPAttribute('features', 'otf-editor')) |
36 | 1 | Adrian Georgescu | return local_media |
37 | 9 | Adrian Georgescu | </pre> |
38 | 1 | Adrian Georgescu | |
39 | 10 | Adrian Georgescu | After session negotiation, the clients can invoke their corespondent GUI elements related to the collaborative editing when detecting off-editor feature in the remote stream. This approach will work with any MSRP implementation, the data will piggy-back on top of an existent chat stream in a non-disruptive way, which makes development of other end-points easy as no internal mechanisms of SIP session session initiation must be done. |
40 | 7 | Adrian Georgescu | |
41 | 1 | Adrian Georgescu | h4. Variant 2 |
42 | 7 | Adrian Georgescu | |
43 | 10 | Adrian Georgescu | Create a complete new media type based on MSRP protocol similar to file-transfer or screen sharing. See SIP SIMPLE Client SDK MSRP streams definition: |
44 | 1 | Adrian Georgescu | |
45 | 1 | Adrian Georgescu | <pre> |
46 | 1 | Adrian Georgescu | sipsimple/streams/msrp.py |
47 | 1 | Adrian Georgescu | </pre> |
48 | 7 | Adrian Georgescu | |
49 | 3 | Adrian Georgescu | Example of a new type of stream |
50 | 3 | Adrian Georgescu | |
51 | 3 | Adrian Georgescu | <pre> |
52 | 3 | Adrian Georgescu | class ODFStream(MSRPStreamBase): |
53 | 3 | Adrian Georgescu | type = 'odf' |
54 | 1 | Adrian Georgescu | |
55 | 3 | Adrian Georgescu | media_type = 'odf' |
56 | 3 | Adrian Georgescu | accept_types = ['application/odf+xml'] |
57 | 3 | Adrian Georgescu | accept_wrapped_types = ['*'] |
58 | 3 | Adrian Georgescu | </pre> |
59 | 1 | Adrian Georgescu | |
60 | 1 | Adrian Georgescu | Once established, the MSRP stream can cary back and forth payloads of the types specified in the stream definition. Is up to the end-points to handle the actual payloads and match various files shared through this mechanism over the same session. The SIP session id can be used to group together various flows within the same stream. |
61 | 7 | Adrian Georgescu | |
62 | 10 | Adrian Georgescu | This mechanism will require similar changes in other clients that wish to implement this feature, it is more complex but have the advantage that it can be negotiated by the use of a SIP Invite where the remote party can accept or reject the call. |
63 | 1 | Adrian Georgescu | |
64 | 6 | Adrian Georgescu | h3. Presence |
65 | 1 | Adrian Georgescu | |
66 | 9 | Adrian Georgescu | Optionally, the end-points supporting this feature can advertise this capability by publishing it using the SIP SIMPLE Presence payload. For this, the end-point capabilities must be extended to support off. |
67 | 1 | Adrian Georgescu | |
68 | 1 | Adrian Georgescu | <pre> |
69 | 4 | Adrian Georgescu | sipsimple/payloads/caps.py |
70 | 1 | Adrian Georgescu | </pre> |
71 | 6 | Adrian Georgescu | |
72 | 6 | Adrian Georgescu | h2. GUI changes |
73 | 6 | Adrian Georgescu | |
74 | 9 | Adrian Georgescu | The GUI must handle sessions for incoming and outgoing media stream defined above by creating its own controller that it is invoked either when negotiating the session, when a proper payload arrives over the chat channel or when user clicks in the GUI. |