Difference between revisions of "Sockets"

From Jmol
Jump to navigation Jump to search
m
(Filled out Basic commands and Arbitrary data sections)
Line 1: Line 1:
 
+
===Why sockets? ===
Jmol supports socket communication between two independent instances that are running on one single or two different computers.  Sockets enable one Jmol instance to send commands to the other for execution. It is also possible to send arbitrary data to be captured in a variable.  The [https://molecularplayground.org/ Molecular Playground] project is a practical application of Jmol sockets.  Jmol socket communication is conducted using the sync command, for which documentation can be found at [https://chemapps.stolaf.edu/jmol/docs/?&fullmanual=1&ver=14.00#sync Jmol docs - sync] and in the [https://chemapps.stolaf.edu/jmol/docs/misc/appsync.txt Inter-Application Communication protocols].
+
Jmol supports socket communication between two independent instances that are running on one single or two different computers.  Sockets enable one Jmol instance to send commands to the other for execution. It is also possible to send arbitrary data to be captured in a variable.  The [https://molecularplayground.org/ Molecular Playground] project is a practical application of Jmol sockets.  Jmol socket communication is conducted using the sync command, for which documentation can be found at [https://chemapps.stolaf.edu/jmol/docs/?&fullmanual=1&ver=14.00#sync Jmol docs sync] and in the [https://chemapps.stolaf.edu/jmol/docs/misc/appsync.txt Inter-Application Communication protocols].  The latter document makes clear that the inter-app messages take the form of JSON-encoded messages such as {"type" : "command", "command" : "background white"}.  Jmol manages this JSON wrapping for us in the nature of the sync command.
 +
===Basic commands ===
 +
Communication between a pair of Jmol applications requires that one be started first with the option -j "sync -8008" (designated server) and a second (client) with -j "sync 8008".  The port 8008 is used as an example; any valid, available port nnnn can be used.  For Jmol-Jmol communication, it's as simple as that.  The appropriate handshake has been exchanged and any subsequent command sent with sync 8008 "command" from either app will result in action at the other.  For example, sync 8008 "background white" entered in the console of the server instance will produce the white background at the client instance (and ''vice-versa'').  For practical purposes, there's no further distinction between the client and server nodes; however, inspection of the traffic reported as stdout in the shell that started each node reveals that the server is sending much more traffic – related to mouse movements and keyboard activity.  This is by design and can be exploited with set syncScript ON and set syncMouse ON.
 +
===Arbitrary data ===
 +
It is handy to define a Jmolscript function ''send'' to simplify command formatting.
 +
:function send (s) {sync 8008 s}    facilitates sending a command as in  send ("load $CC")
 +
It's yet more useful when the target Jmol also has a function ''send''.
 +
:send ("function send (s) {sync 8008 s}") will define the same function at the client.
 +
The command sequence
 +
:send ("load $CC")                    (1)
 +
:send ('c=write("coords")')            (2)
 +
:send('send ("d=\' " + c + "\' ")')    (3)
 +
results in a model of ethane on the client (1) from which the xyz format coordinates are stored initially in ''var c'' on the client (2) and finally sent back to the server to be stored in ''var d'' on the server (3) as subsequently can be demonstrated by
 +
:print d; load '@d'
 +
Note that the single and double (and escaped \') quotes in (3) are a necessary pattern to produce a command that the client can execute as
 +
send (" 'd = ' c") where ''d ='' is string that the server treats as symbol and loads it with the contents of ''c''.  There are other patterns that will accomplish the same result within the constraint that the JSON-encoded {"type" : "command", "command" : 'send ("d=\' " + c + "\' ")'} is how it travels over the socket.

Revision as of 00:23, 25 January 2023

Why sockets?

Jmol supports socket communication between two independent instances that are running on one single or two different computers. Sockets enable one Jmol instance to send commands to the other for execution. It is also possible to send arbitrary data to be captured in a variable. The Molecular Playground project is a practical application of Jmol sockets. Jmol socket communication is conducted using the sync command, for which documentation can be found at Jmol docs – sync and in the Inter-Application Communication protocols. The latter document makes clear that the inter-app messages take the form of JSON-encoded messages such as {"type" : "command", "command" : "background white"}. Jmol manages this JSON wrapping for us in the nature of the sync command.

Basic commands

Communication between a pair of Jmol applications requires that one be started first with the option -j "sync -8008" (designated server) and a second (client) with -j "sync 8008". The port 8008 is used as an example; any valid, available port nnnn can be used. For Jmol-Jmol communication, it's as simple as that. The appropriate handshake has been exchanged and any subsequent command sent with sync 8008 "command" from either app will result in action at the other. For example, sync 8008 "background white" entered in the console of the server instance will produce the white background at the client instance (and vice-versa). For practical purposes, there's no further distinction between the client and server nodes; however, inspection of the traffic reported as stdout in the shell that started each node reveals that the server is sending much more traffic – related to mouse movements and keyboard activity. This is by design and can be exploited with set syncScript ON and set syncMouse ON.

Arbitrary data

It is handy to define a Jmolscript function send to simplify command formatting.

function send (s) {sync 8008 s} facilitates sending a command as in send ("load $CC")

It's yet more useful when the target Jmol also has a function send.

send ("function send (s) {sync 8008 s}") will define the same function at the client.

The command sequence

send ("load $CC") (1)
send ('c=write("coords")') (2)
send('send ("d=\' " + c + "\' ")') (3)

results in a model of ethane on the client (1) from which the xyz format coordinates are stored initially in var c on the client (2) and finally sent back to the server to be stored in var d on the server (3) as subsequently can be demonstrated by

print d; load '@d'

Note that the single and double (and escaped \') quotes in (3) are a necessary pattern to produce a command that the client can execute as send (" 'd = ' c") where d = is string that the server treats as symbol and loads it with the contents of c. There are other patterns that will accomplish the same result within the constraint that the JSON-encoded {"type" : "command", "command" : 'send ("d=\' " + c + "\' ")'} is how it travels over the socket.

Contributors

GWhitwell