modo 501 introduces a basic telnet server. This allows third party applications to control modo via a TCP connection using either the telnet protocol or a raw stream of text. For the purposes of this article, both the actual telnet protocol and raw text mode are referred to as telnet, even though raw text is technically not part of the telnet specification.
Once connected to the socket, controlling modo via telnet is exactly the same as controlling modo through headless mode, and can be run from both headless mode and from the GUI, with the caveat that it is possible for the user to try to interact with the modo interface at the same time when in GUI mode. Telnet and user-initiated commands will never execute simultaneously, and pending telnet commands will be cached until the user (and modo itself) is idle. Similarly, the output sent back to the connected remote host will only be responses to commands it executed, and will not contain a stream of results from all modo commands.
Only one' remote host can be connected to modos open telnet port at any given time. The connection can be made with any program that supports the telnet protocol (or the raw text mode, if you open the port in that manner), such as the one that comes with your operating system, or by opening a connection from a script or another application. Since telnet is TCP based, you can control modo over the LAN or even the internet (if you're feeling adventurous), or directly from the local machine.
What Can Be Sent
Telnet operates just like headless mode. You send commands to be executed and queried, and modo sends back formatted results. As with headless, you will get a prompt when the server is idle and is ready for you to send it more commands.
When Commands are Executed
The telnet server caches commands, executing them one at a time. The application must be idle before any telnet-sourced commands are executed. This means that all keys and mouse buttons must be up, all popups, popovers and modal windows must be closed, and no other commands can be executing at the time. This means that if a command is already executing (say, because the user is using the mouse to interact with modo, or because a frame is rendering, etc), it will wait until that command has finished before firing the pending command. It is not necessary to wait for a command to finish executing before sending another command, although it is good practice to send commands one at a time so that you can perform appropriate error handling should a one fail.
Sending Comment Lines
You may also send a comment line by prefixing it with a #. Comment lines are ignored by modo, and will simply be echoed back out over the telnet connection.
Telnet Mode vs. Raw Mode
The modo telnet server supports two modes. The default mode supports the basics of the telnet protocol, as described in RFC854. The implementation is pretty basic, with it rejecting all options on connection and behaving as a simple terminal. Lines are expected to end with /r/n or /r/0, and ASCII 255 is used for telnet control codes, most of which are simply ignored. This mode is most useful when testing with a true telnet client.
Raw mode is more useful for controlling modo through another application or script. In this mode, lines end with the ASCII NUL character /0, and no control codes are present.
In general, you will use telnet mode if you're connecting with a standard telnet-compatible client, and raw mode if you're communicating with modo through a custom script or application. You can use telnet mode to communicate through a custom script or application, but raw mode is simpler and requires less work on the developer's end.
Both headless and GUI modo can be controlled via telnet. To run headless mode with telnet support, you must explicitly launch it with the -telnet: switch. You can also use with the modo GUI so that telnet is available right after modo starts up. When used in headless mode, only telnet communication is supported -- you cannot type commands into the terminal.
modo_cl.exe -telnet:12357 modo_cl.exe -telnet:telnet@12357 modo_cl.exe -telnet:raw@12357 |-|
modo.app/Contents/MacOS/modo -telnet:12357 modo.app/Contents/MacOS/modo -telnet:telnet@12357 modo.app/Contents/MacOS/modo -telnet:raw@12357 </tabber>
The first two will execute modo and start listening on port 12357 for incoming telnet connections in telnet mode, while the third one will open on port 12357 in raw mode. Note that the application will remain running once the connection is severed, thus allowing new clients to connect. The application can be quit directly with App.quit, or automatically when the connection is lost with Telnet.quitOnDisconnect.
To start listening for telnet connections from modo's GUI, execute the Telnet.listen command.
telnet.listen <port:integer> <raw:boolean> ?<open:boolean>
port is the port number that modo should listen on for incoming telnet connections. Only one remote host can be connected at a time, and the telnet server will continue listening for new connections until the server is stopped. This argument is required when opening the socket for listening, but can be omitted when closing it.
raw determines if the socket should support the telnet protocol as described above, or be used as a raw communications channel. By default, connections opened in telnet mode.
open is true by default, and causes the server to start listening on the port provided. If false, it will close the port and stop listening. Note that any connected remote hosts will remain connected on close; this simply keeps anyone else from trying to connect after the current connection is severed.
This starts listening for connections on port 12357 in raw mode.
telnet.listen 12357 true
This stops listening for connections. Again, if someone is already connected, they will remain connected, but no one else will be able to connect.
To close a connection with a remote host, use Telnet.close. This will normally attempt to close the connection gracefully, but it can also perform an immediate hard disconnect by setting the the force argument to true.
Quitting modo from Telnet
There are times when it is useful for a controlling application to tell modo to quit. One way is to call the App.quit command from within modo, which will cause modo to quit immediately. Another way is to tell modo to quit when the connection is severed. This is done with the Telnet.quitOnDisconnect command.
Setting the state to true will cause modo to quit when the connection is lost. The main reason to use this command instead of app.quit is to handle unexpected errors. For example, if the network connection between the processes goes down, or if the controlling application crashes, modo would still be running in a limbo state, using up resources although no one using it anymore. By executing telnet.quitOnDisconnect, modo will clean up and quit when the connection is lost.
The telnet system supports some fairly verbose logging to the event log. This can be enabled with the Log.subEnable command.
Logging include information about connections and disconnections, as well as all of the strings sent back and forth between modo and the remote host.
It is also possible to send newly logged events over telnet as the events come in by using Log.toConsole and Log.toConsoleRolling. Specific log subsystems can then be toggled on and off via the Log.subToConsole and Log.subToConsoleOnly commands, and reset to show all log entries through Log.consoleReset. log.toConsoleRolling is commonly used when rendering.