Changes between Version 7 and Version 8 of Infinote/Protocol

Show
Ignore:
Timestamp:
09/23/08 23:58:56 (5 years ago)
Author:
armin (IP: 87.178.240.102)
Comment:

Updated directory messages

Legend:

Unmodified
Added
Removed
Modified
  • Infinote/Protocol

    v7 v8  
    4242}}} 
    4343 
    44 Scope can be either "ptp" (point-to-point) or "group". If scope is "ptp", then message is only for the recipient. If scope is "group", the message is for the whole group. In this case the receiver needs to relay the message to all the group members that do not yet have received the message (which is depending on and performed by the communication method). 
     44Scope can be either "ptp" (point-to-point) or "group". If scope is "ptp", then message is only for the recipient. If scope is "group", the message is for the whole group. In this case the receiver needs to relay the message to all the group members that do not yet have received the message (which is depending on and performed by the communication method). (TODO: Remove the scope field, the recipient should decide from the content whether the message is one for all group members or not). 
    4545 
    4646Each group has a publisher which is the host that opened the group. For each network that the host is part of, the host needs a unique identification string. For example, a host could be part of both a TCP/IP and a Jabber network. Then, the publisher ID could be its JID on the jabber network and its IP and Port number (in a normalized form) on the TCP/IP network. The term network here refers to the fact that members of a network cannot technically communicate with members of another network. So, if a message contains a given publisher string, all potential recipients can identify the corresponding host. 
     
    5050=== Communication Methods === 
    5151 
    52 TODO 
    53  
    54 == Directory == 
    55  
    56 Directory handling is done within the 'InfDirectory' group. The following messages are defined: 
     52A communication method defines how a message from a group member is delivered to the other group members. Each method is identified by a name. Communication methods can send control messages to other group members. These can be used for method-internal communication. Control messages look like this: 
     53 
     54{{{ 
     55<control name="InfDirectory" publisher="armin@0x539.de"> 
     56 <more-content /> 
     57</group> 
     58}}} 
     59 
     60Again, name denotes the group name and publisher the group publisher, so the control message can be related to a group. Control messages are always point-to-point (ptp). Currently, the following methods are used: 
     61 
     62 * central: The central messages sends all group-related messages to the publisher, and the publisher relays the message to all clients. This means that when the publisher has lost its connection to the network, then group messages can no longer be delivered. 
     63 * more to follow (peer-to-peer, groupchat, ...) 
     64 
     65== Directory messages == 
     66 
     67This section describes the messages an infinote client or server need to handle for the directory of documents. With server, we mean a host that exposes its directory and allows others to edit the contained documents collaboratively. The client is the remote counterpart, it can browse the server's directory and decide to edit documents hosted on the remote server. 
     68 
     69In general, any node within the directory is associated a unique ID which is an unsigned integral number. The ID can be used to refer to a specific node in the tree. The root node always has ID 0. Also, any node has a type. Nodes of type "Subdirectory" are simply containers for more nodes, nodes with other types are document nodes. For example, nodes representing a plain text document have type "InfText". Other node types might be implemented in the future. 
     70 
     71Directory handling is done within the 'InfDirectory' group using the 'central' method. 
    5772 
    5873=== Client Side === 
    5974 
     75The following messages are defined on the client side, meaning an infinote server needs to handle these. Apart from the explained messages the server replies with, the server might reply with <request-failed> to any request (see Server Side below for a more detailed explanation of that message). 
     76 
    6077{{{ 
    6178<explore-node id="node_id" seq="seq_id" /> 
    6279}}} 
    6380 
    64  * id, Integer: The node ID to explore. Each node in the Directory has an ID. The root node has ID 0. 
    65  * seq, Integer, optional: An optional ID for the request. The server reply will have the same seq set. 
    66  
    67 Explores the node with the given ID. The server replies with <explore-begin>, <add-node> and <explore-end> messages. 
    68  
    69 {{{ 
    70 <add-node parent="node_id" type="Type" name="Name" seq="seq_id" /> 
     81 * id, Integer: The node ID to explore. The ID needs to refer to a subdirectory type of node. 
     82 * seq, Integer, optional: An optional sequence number for the request. The server reply will have the same seq set. 
     83 
     84Explores the node with the given ID. This means that the client requests a list of all nodes contained in the refered subdirectory node. The server replies with single <explore-begin> message, then an arbitrary amount of <add-node> messages and a final <explore-end> message. All of these messages have seq_id for the sequence number set, if seq was provided. 
     85 
     86It is only allowed to explore a node once. However, when having explored a node, then the server notifies the client about about changes such as node additions or removals within that subdirectory. 
     87 
     88{{{ 
     89<add-node parent="node_id" type="Type" name="Name" seq="seq_id"><sync-in /><subscribe /></add-node> 
    7190}}} 
    7291 
    7392 * parent, Integer: The node ID of the parent node. This must refer to a subdirectory node. 
    74  * type, (InfSubdirectory|InfText): The type of the node to create. Different node types may be supported in the future. 
     93 * type, NodeType: The type of the node to create. 
    7594 * name, String: The name of the new node. Must not contain the '/' character. 
    76  * seq, Integer, optional: An optional ID for the request. The server reply will have the same seq set. 
    77  
    78 Adds a new node to the server's directory. The server replies with <add-node>. 
     95 * seq, Integer, optional: An optional sequence number for the request. The server reply will have the same seq set. 
     96 * <sync-in />, optional: If <sync-in /> is set, then the client will requests to provide initial content for the document, otherwise the server creates an empty document. This is only valid if type is not "InfSubdirectory". 
     97 * <subscribe />, optional: If <subscribe /> is set, then the client requests to initially be subscribed to the session the new node represents. This is only valid if type is not "InfSubdirectory". 
     98 
     99Adds a new node to the server's directory. The server replies with <add-node> or <sync-in>, depending on whether <sync-in /> is set or not. 
    79100 
    80101{{{ 
     
    83104 
    84105 * id, Integer: The node ID to remove. If it is a subdirectory, all children are removed recursively. 
    85  * seq, Integer, optional: An optional ID for the request. The server reply will have the same seq set. 
     106 * seq, Integer, optional: An optional sequence number for the request. The server reply will have the same seq set. 
    86107 
    87108Removes a node from the server's directory. The server replies with <remove-node> 
     
    92113 
    93114 * id, Integer: The node ID of the document whose session to join. Must not refer to a subdirectory node. 
    94  * seq, Integer, optional: An optional ID for the request. The server reply will have the same seq set. 
     115 * seq, Integer, optional: An optional sequence number for the request. The server reply will have the same seq set. 
    95116 
    96117Requests subscription to the session refered to by node_id. The server replies with <subscribe-session> 
     
    105126 
    106127 * domain, String: The domain where the error came from. The most important domain is "INF_DIRECTORY_ERROR". 
    107  * code, Integer: A numerical error code identifying what went wrong. This depends on the error domain. 
     128 * code, Integer: A numerical error code identifying what went wrong. The meaning depends on the error domain. 
    108129 * seq, Integer: The seq_id the client had set in the original request that failed, if any. 
    109130 * text, optional: Human-readable error message in the server's language. 
     
    111132This is sent if a client request could not be processed, for example because it refered to a directory node that does not exist. 
    112133 
     134TODO: List all possible error domains and codes somewhere. 
     135 
    113136{{{ 
    114137<explore-begin total="num" seq="seq_id" /> 
     
    118141 * seq, Integer: The seq_id the client had set in the original <explore-node> request, if any. 
    119142 
    120 Server reply to a <explore-node> request. This is followed by total <add-node> and an <explore-end> message. 
     143Server reply to a <explore-node> request. This is followed by total <add-node> and one <explore-end> message. 
    121144 
    122145{{{ 
     
    129152 
    130153{{{ 
    131 <add-node id="node_id" parent="node_id" type="Type" name="Name" seq="seq_id"/> 
     154<add-node id="node_id" parent="node_id" type="Type" name="Name" seq="seq_id"> 
     155 <subscribe group="group_name" method="method_name" /> 
     156</add-node> 
    132157}}} 
    133158 
    134159 * id, Integer: The node ID of the added node 
    135160 * parent, Integer: The node ID of the parent node (which is a subdirectory) 
    136  * type, (InfSubdirectory|InfText): The type of the new node. 
     161 * type, NodeType: The type of the new node. 
     162 * name, String: The name of the new node. 
    137163 * seq, Integer: The seq_id the client had set in the original <explore-node> or <add-node> request, if any. 
     164 * <subscribe />, optional: If set, then the client is considered subscribed to the newly created session (in which case type must not be "InfSubdirectory"). 
     165   * group, String: The group name of the subscription group for the session. The subscription group is the group for all connections subscribed to a session. The publisher of the subscription group is always the same as the one of the InfDirectory group. 
     166   * method, String: The communication method that is used to deliver messages in that group. 
    138167 
    139168The server notifies the client that a new node has been added to the directory, within a subdirectory that the client already explored. Also used when a client currently explores a subdirectory. 
    140169 
    141 {{{ 
    142 <remove-node id="node_id" seq="seq_id"> 
     170If <subscribe /> is set, then the client is subscribed to the session that the new node refers to. This is normally only used if the client explicitely requested subscription in its <add-node> request. Therefore the session is _not_ synchronized to the client, since both sides know the content already anyway (the session is initially empty). 
     171 
     172{{{ 
     173<sync-in id="node_id" parent="node_id" type="Type" name="Name" method="method_name" group="group_name" seq="seq_id"> 
     174 <subscribe group="group_name" method="method_name" /> 
     175</sync-in> 
     176}}} 
     177 
     178 * id, Integer: The node ID of the added node 
     179 * parent, Integer: The node ID of the parent node (which is a subdirectory) 
     180 * type, NodeType: The type of the new node (this is never "InfSubdirectory") 
     181 * name, String: The name of the new node 
     182 * seq, Integer: The seq_id the client had set in the original <add-node> request, if any. 
     183 * group, String: The group name of the synchronization group. The synchronization group is used to synchronize the initial session content from the client to the server. The publisher of the synchronization group is always the same as the one of the InfDirectory group. 
     184 * method, String: The communication method used to deliver messages within the synchronization group. 
     185 * <subscribe />, optional: If set, then the client is considered subscribed to the newly created session. 
     186   * group, String: The group name of the subscription group for the session. The subscription group is the group for all connections subscribed to a session. The publisher of the subscription group is always the same as the one of the InfDirectory group. 
     187   * method, String: The communication method that is used to deliver messages in that group. 
     188 
     189This can only be sent in response to a <add-node> request from a client with <sync-in /> set. It also notifies the client about a new node creation, and tells the client the group name and method for the synchronization group. The client then synchronizes the initial session content within that group. See more on this below, in the Session messages section. 
     190 
     191If <subscribe /> is set, then the client is subscribed to the session that the new node refers to. This is normally only used if the client explicitely requested subscription in its <add-node> request. Normally, the subscription group and method will be the same as the synchronization group and method, but they can also be different. However, if the group name is the same, then the method needs to be the same as well (because it refers to the same group). 
     192 
     193{{{ 
     194<remove-node id="node_id" seq="seq_id" /> 
    143195}}} 
    144196 
    145197 * id, Integer: The node ID of the removed node. 
    146  * seq_id, Integer: The seq_id the client had set in the original <remove-node> request, if any. 
     198 * seq, Integer: The seq_id the client had set in the original <remove-node> request, if any. 
    147199 
    148200The server notifies the client that a node has been removed from the directory, within a subdirectory that the client already explored. 
    149201 
    150202{{{ 
    151 <subscribe-session id="node_id" group="group" seq="seq_id"> 
    152 }}} 
    153  
    154  * id, Integer: The ID of the document whose session the client is subscribed to. Must not be a subdirectory node. 
    155  * group: The group for that subscription. 
    156  * seq: The seq_id the client had set in the original <subscribe-session> request, if any. 
    157  
    158 Subscribes the client to a session. This goes on by synchronizing the session to the client within the specified group. 
     203<subscribe-session id="node_id" group="group_name" method="method_name" seq="seq_id" /> 
     204}}} 
     205 
     206 * id, Integer: The ID of the document whose session the client is subscribed to. Must not refer to a subdirectory node. 
     207 * group, String: The group name of the subscription group. The subscription group is the group for all connections subscribed to a session. The publisher of the subscription group is always the same as the one of the InfDirectory group. 
     208 * method, String: The communication method used to deliver messages within the subscription group. 
     209 * seq, Integer: The seq_id the client had set in the original <subscribe-session> request, if any. 
     210 
     211Subscribes the client to a session. The server will now synchronize the session's content to the client within the subscription group. 
    159212 
    160213=== Example === 
    161214 
    162215{{{ 
    163 <message from="phil@0x539.de" to="armin@0x539.de"> 
    164  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    165   <explore-node seq="0" id="0"/> 
    166  </group> 
    167 </message> 
    168 }}} 
    169  
    170 Client phil@0x539.de wants to explore the root node of the directory at armin@0x539.de. 
    171  
    172 {{{ 
    173 <message from="armin@0x539.de" to="phil@0x539.de"> 
    174  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    175   <explore-begin total="3" seq="0"/> 
    176  </group> 
    177 </message> 
    178 <message from="armin@0x539.de" to="phil@0x539.de"> 
    179  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    180   <add-node id="3" parent="0" name="first" type="InfSubdirectory" seq="0"/> 
    181  </group> 
    182 </message> 
    183 <message from="armin@0x539.de" to="phil@0x539.de"> 
    184  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    185   <add-node id="2" parent="0" name="third" type="InfSubdirectory" seq="0"/> 
    186  </group> 
    187 </message> 
    188 <message from="armin@0x539.de" to="phil@0x539.de"> 
    189  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    190   <add-node id="1" parent="0" name="second" type="InfSubdirectory" seq="0"/> 
    191  </group> 
    192 </message> 
    193 <message from="armin@0x539.de" to="phil@0x539.de"> 
    194  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    195   <explore-end seq="0"/> 
    196  </group> 
    197 </message> 
    198 }}} 
    199  
    200 Server reply. This could also be packed within a single <message> and <group>, respectively, but it would then be sent as a single XMPP message. The client then has no chance to get progress information before the exploration is finished, and a single, big message could block traffic in other groups that go through the same connection. 
    201  
    202 {{{ 
    203 <message from="phil@0x539.de" to="armin@0x539.de"> 
    204  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    205   <explore-node seq="1" id="1"/> 
    206  </group> 
    207 </message> 
    208 }}} 
    209  
    210 Phil wants to explore another node. 
    211  
    212 {{{ 
    213 <message from="armin@0x539.de" to="phil@0x539.de"> 
    214  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    215   <explore-begin total="2" seq="1"/> 
    216  </group> 
    217 </message> 
    218 <message from="armin@0x539.de" to="phil@0x539.de"> 
    219  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    220   <add-node id="5" parent="1" name="bar" type="InfSubdirectory" seq="1"/> 
    221  </group> 
    222 </message> 
    223 <message from="armin@0x539.de" to="phil@0x539.de"> 
    224  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    225   <add-node id="4" parent="1" name="foo" type="InfSubdirectory" seq="1"/> 
    226  </group> 
    227 </message> 
    228 <message from="armin@0x539.de" to="phil@0x539.de"> 
    229  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    230   <explore-end seq="1"/> 
    231  </group> 
    232 </message> 
    233 }}} 
    234  
    235 I think that is self-explanatory. 
    236  
    237 {{{ 
    238 <message from="phil@0x539.de" to="armin@0x539.de"> 
    239  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    240   <add-node seq="2" parent="1" type="InfSubdirectory" name="baz"/> 
    241  </group> 
    242 </message> 
    243 }}} 
    244  
    245 Phil wants to create a new subdirectory called "baz" within the "second" subdirectory. 
    246  
    247 {{{ 
    248 <message from="armin@0x539.de" to="phil@0x539.de"> 
    249  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    250   <add-node id="6" parent="1" name="baz" type="InfSubdirectory" seq="2"/> 
    251  </group> 
    252 </message> 
     216<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     217 <explore-node seq="0" id="0"/> 
     218</group> 
     219}}} 
     220 
     221Some client wants to explore the root node of the directory of the server with publisher id armin@0x539.de. 
     222 
     223{{{ 
     224<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     225 <explore-begin total="3" seq="0"/> 
     226</group> 
     227<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     228 <add-node id="3" parent="0" name="first" type="InfSubdirectory" seq="0"/> 
     229</group> 
     230<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     231 <add-node id="2" parent="0" name="third" type="InfSubdirectory" seq="0"/> 
     232</group> 
     233<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     234 <add-node id="1" parent="0" name="second" type="InfSubdirectory" seq="0"/> 
     235</group> 
     236<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     237 <explore-end seq="0"/> 
     238</group> 
     239}}} 
     240 
     241Server reply. This could also be packed within a single <group> message, but it would then be sent as a single message and could not be sent in chunks. A single, big message could block traffic in other groups that go through the same connection this way. 
     242 
     243{{{ 
     244<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     245 <explore-node seq="1" id="1"/> 
     246</group> 
     247}}} 
     248 
     249The client wants to explore another node. 
     250 
     251{{{ 
     252<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     253 <explore-begin total="2" seq="1"/> 
     254</group> 
     255<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     256 <add-node id="5" parent="1" name="bar" type="InfSubdirectory" seq="1"/> 
     257</group> 
     258<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     259 <add-node id="4" parent="1" name="foo" type="InfSubdirectory" seq="1"/> 
     260</group> 
     261<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     262 <explore-end seq="1"/> 
     263</group> 
     264}}} 
     265 
     266That is probably self-explanatory. 
     267 
     268{{{ 
     269<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     270 <add-node seq="2" parent="1" type="InfSubdirectory" name="baz"/> 
     271</group> 
     272}}} 
     273 
     274The client wants to create a new subdirectory called "baz" within the "second" subdirectory. 
     275 
     276{{{ 
     277<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     278 <add-node id="6" parent="1" name="baz" type="InfSubdirectory" seq="2"/> 
     279</group> 
    253280}}} 
    254281 
     
    256283 
    257284{{{ 
    258 <message from="phil@0x539.de" to="armin@0x539.de"> 
    259  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    260   <add-node seq="3" parent="1" type="InfSubdirectory" name="baz"/> 
    261  </group> 
    262 </message> 
     285<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     286 <add-node seq="3" parent="1" type="InfSubdirectory" name="baz"/> 
     287</group> 
    263288}}} 
    264289 
     
    266291 
    267292{{{ 
    268 <message from="armin@0x539.de" to="phil@0x539.de"> 
    269  <group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
    270   <request-failed code="0" domain="INF_DIRECTORY_ERROR" seq="3"/> 
    271  </group> 
    272 </message> 
    273 }}} 
    274  
    275 But this does not work. Error code 0 in the INF_DIRECTORY_ERROR domain means "Node already exists". 
    276  
    277 == Session == 
     293<group name="InfDirectory" publisher="armin@0x539.de" scope="ptp"> 
     294 <request-failed code="0" domain="INF_DIRECTORY_ERROR" seq="3"/> 
     295</group> 
     296}}} 
     297 
     298But this does not work. Error code 0 in the INF_DIRECTORY_ERROR domain means "Node with that name already exists". 
     299 
     300== Session messages == 
    278301 
    279302Each session has a so-called subscription group, that is a group of which all subscribed connections are a member. The group name for that group is specified by the server (who is also the publisher of the group). Session joins can only be performed at the server, however, once joined, the session can go on even if the connection to the server is lost (assuming the other subscribed hosts are still reachable).