The SockHop BMessage protocol

The SockHop node tree communicates with user code solely by means of BMessages.  When you create the root SockHop node, you pass in a BMessenger object to the SHCreateRootNode() function.  Whenever SockHop wants to tell you something, it will send a BMessage via this BMessenger.  Your receiving code (which can be a BLooper object or anything else that a BMessenger can send to) can then handle the BMessage as it sees fit.  The root node object returned by SHCreateRootNode() is a type of BLooper, so to send a BMessage to SockHop, all you need to do is call PostMessage() on the root node object.

All the BMessage 'what' values that SockHop recognizes are enumerated in the header file <sockhop/SockHopConstants.h>.  The command codes all have the form SH_COMMAND_(something).  If you send SockHop a BMessage with any other value besides these, it will assume that the BMessage is meant for add-on code (SHSorters or SHWorkers) and will route the BMessage normally and give it to the SHWorkers on any receiving nodes.

In addition to the 'what' code, SockHop also looks in each BMessage you send it for certain fields.  These fields are also enumerated in <sockhop/SockHopConstants.h>, and are listed with names that have the form SH_NAME_(something).  The field name values all start with the lower case letters "sh", followed by a capital letter, and possibly some additional letters.  To avoid possible conflicts and confusion, it is strongly suggested that your code not use similarly named fields in BMessages for its own purposes.  Furthermore, it is suggested that you always use the SH_NAME_* identifiers in your code instead of the actual strings they represent.  This reduces the chances of typos going uncaught in your code, and make it easier to recompile your code for new versions of SockHop should the string values ever change.
 
SH_COMMAND 'what' values that SockHop understands, and what they mean.


This actually isn't a SockHop command, it's just here to mark the beginning of the command value range.  SockHop will treat BMessages with this 'what' value the same as any user message type.


 
Fields that can be added to an SH_COMMAND_ADDCOMPONENTS BMessage
SH_NAME_SORTERS This field should be an array of one or more BMessages that were generated by calling the Archive() method on SHSorter-subclass objects.  The receiving node(s) will download and unarchive each SHSorter in this array, and add them to their list of active SHSorters.
SH_NAME_WORKERS This field should be an array of one or more BMessages that were generated by calling the Archive() method on SHWorker-subclass objects.  The receiving node(s) will download and unarchive each SHWorker in this array, and add them to their list of active SHWorkers.
SH_NAME_CHILDREN This field should be an array of one or more flattened SHNodeSpecs, each added to the BMessage via AddFlat().  Each SHNodeSpec in the array represents a description of a new node that the receiver of this BMessage should create and connect to.   The new nodes are added to the tree as children of the node that received this BMessage.
SH_NAME_FILES This field should be an array of one or more flattened SHFileSpecs, each added to the BMessage via AddFlat().  Each SHFileSpec represents one set of files that should be cached on the receiving node(s).  The node will read each SHFileSpec and make sure that it has an up-to-date version of each file that the SHFileSpec specifies.  If it does not, it will request a copies of the missing/out-of-date files from the nodes above it in the tree.
SH_NAME_SYMLINKS Not filesystem symlinks!  This field should be an array of one or more strings.  It works somewhat similarly to the SH_NAME_CHILDREN field (described above), except that instead of instantiating new child nodes, it creates "fake" children that are really pointers to currently existing nodes.  Each string in this field should contain a node path designating one or more target nodes in the tree.  Each node path may contain wildcards, in which case more than one symlink may be created.  Each symlink that is created will appear as a child underneath the connecting node, and will have the same name as the node that was connected to. 

NOTE:  Be careful when creating symlinks that cause cycles in the node graph!  It opens the door to potential infinite loops of BMessage transmission (e.g., using the default sorter and not specifying an SH_NAME_TO field in a BMessage would cause a broadcast transmission that would cycle through the graph indefinitely!) 

 
 
Fields that can be added to an SH_COMMAND_REMOVECOMPONENTS BMessage
SH_NAME_SORTERS This field should be an array of one or more strings.  Each string in the array should be a regular expression that will be compared against the names of the SHSorters in the receiving node's worker list.  The receiving node will remove and delete any SHSorters whose names match one or more of the regular expressions in this field.
SH_NAME_WORKERS This field should be an array of one or more strings.  Each string in the array should be a regular expression that will be compared against the names of the SHWorkers in the receiving node's worker list.  The receiving node will remove and delete any SHWorkers whose names match one or more of the regular expressions in this field.
SH_NAME_CHILDREN This field should be an array of one or more strings.  Each string in the array should be a regular expression that will be compared against the names of the child nodes of the receiving node.  The receiving node will remove any children whose names match one or more of the regular expressions in this field.  If the removed children are "real" children, this will cause them to be destroyed; if the removed children are actually symlinks, this will just remove the symlink to the child without affecting the child itself.
SH_NAME_FILES This field should be an array of one or more flattened SHFileSpecs.  Each receiving node will iterate over each SHFileSpec in the array, and delete from the local filesystem every file specified by each SHFileSpec.
SH_NAME_SYMLINKS This works the same as the SH_NAME_CHILDREN field (see above), except that it will only affect symlink children--connections to real children are not broken.