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.
You can send a BMessage of this command type to any node in the SockHop tree, to tell it to add various things to itself. Specifically, you can tell it to create and add files, symlinks, new child nodes, new SHWorkers, and/or new SHSorters. For objects that require an add-on file, SockHop will automatically download and cache the add-on file as necessary, to any node where the objects in that add-on file are to be instantiated. When a SockHop node receives a BMessage of this type, it will look for the following fields in the BMessage (any or all of these fields may be present):
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!) |
You can send a BMessage of this command type to any node in the SockHop tree, to tell it to remove various things from itself. In particular, you can tell it to delete files, child nodes, symlinks, SHWorkers, and/or SHSorters. When a SockHop node receives a BMessage of this type, it will look for the following fields in the BMessage (any or all of these fields may be present):
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. |
This command can be used to set various miscellaneous parameters on
the receiving node. Parameter names and values should be added directly
to the BMessage, with the parameter's name being the field name, and the
value being the data associated with that field.
SH_PARAMNAME_DEBUG | An int32 field. Sets the debug output level of the targetted nodes. Currently, there are only two levels: 0 (no debug output), and non-zero (debug output) |
SH_PARAMNAME_DEFAULTSORTER | A string field. Sets the default sorter for the receiving node to the first one of the node's available sorter list whose GetName() method returns the string specified in this field. |
SH_PARAMNAME_THREADPRIORITY | An int32 field. Sets the thread priority that will be given to newly spawned SockHop threads. |
SH_PARAMNAME_TRANSMISSIONENCODING | An int32 field. Sets the BMessage encoding that will be used by newly spawned TCP connections. The value given here should be one of the SH_ENCODING_* tokens specified in SockHopConstants.h. |
Click here for an example of how to use SH_COMMAND_SETPARAMETERS.
This command can be used to query a node for the state various parameters. The names of the parameters you are interested in should be added to the BMessage with AddString(parameterName, ""), and fields with same names and the appropriate values will be added to the SH_NAME_ONSUCCESS message that is sent back. Note that this command is pretty useless unless you do specify an SH_NAME_ONSUCCESS field with it!
For a list of valid parameter names, see the SH_COMMAND_SETPARAMETERS documentation.
Click here for examples of how to use SH_COMMAND_GETPARAMETERS.
This command tells the receiving node to terminate. When a node terminates, all descendants of that node are implicitely terminated as well. (This message type has the same effect as calling Lock() and Quit() on the receiving node)
This isn't a real command either, but rather just serves to mark the end of the current SH_COMMAND_* range. If a BMessage with this type is sent, it will be interpreted as a regular user message.