SocketServer - A simple server for messaging between applications and/or computers

Download socketserver version 1 here

In developing exhibits, I often have communication needs that extend beyond the capabilities of the programming languages I use. For these situations, I have written a simple server to pass messages back and forth between applications and/or computers. I have also written a number of different clients; some just broadcast messages periodically for testing, some relay messages back and forth with serial ports (or usb-to-serial devices), and some take action on the messages and change their displayed output (like a flash client). Here are some examples of situations in which such a system would be necessary:

  • A physical device for control of a Flash application. This could be something like an Arduino, a Make Board, or any other device that connects to a serial port or a usb port via a serial>usb chip. Flash can't talk directly to the serial port that the device is connected to, but it can talk directly to this server, and another client handles the serial-to-server messages
  • Several machines, all running Flash software. Content of one machine is controlled by user input, content of the other machines is controlled by what the main machine tells them to show.
  • One machine running a Flash application; in Flash, file system operations are limited to the application's current working directory and subdirectories, so they are instead handled through the server and another client (that isn't restricted to CWD/subdirectories) handles the file requests and commands.
  • Several different types of applications running on one or multiple machines; so long as each of these applications can make a TCP/IP Socket connection, they can all talk to each other.

The majority of the work I do obviously involves Flash, but I've occasionally needed other programs to talk back and forth, and the simplicity of this server has made these communications easy.

The server itself is written in PHP (CLI php, not the Apache plugin that returns website requests). CLI PHP is installed and enabled in the most recent versions of Mac OS 10. It can be quickly and easily installed on most Linux machines; just use a package manager and find CLI PHP. Unfortunately, there is enough variation between PHP on *nix systems and PHP on Windows systems that the server will not currently run on a Windows machine. I have a version of the server that was written specifically for Windows, so at some point in the near future I plan on bringing that code into the application... I'm just not in a big rush because 98% of the time I'm working in 10.5.

So here's how the server works:

  1. Download this compressed folder.
  2. Decompress it.
  3. Open a terminal application... on a mac, use 'Terminal' in the Applications/Utilities directory. Most linuxes can start a terminal from their gui, usually by going Applications > Accessories > Terminal.
  4. Navigate in terminal to the decompressed directory. The command 'cd' means 'change directory', so if you are on a mac and you decompressed this to your desktop you would type 'cd Desktop/socketserverv1'. If you are new to a terminal, try a few other neat commands; 'ls' means list and will give you a list of the current directory's contents. 'cd ..' means 'go to the parent directory of where I am.' If you think that your application requires the functionality of something like socketserver and you are unfamiliar with Terminal, I highly recommend reading up on BASH, shell scripts, and all the other neat stuff a terminal can do.
  5. Start the server with a command like './socketserver.sh -v'. This command says to start the server with default settings and run in verbose mode ('-v'), so you can see what's happening.
  6. If you get a permission denied error when trying to launch the server, the server isn't set up to be executable. Make it executable by typing 'chmod 0777 socketserver.sh'.
  7. At this point, the server should actually be running, and the default settings are localhost (127.0.0.1) and port 6780. You can talk to the server by opening a new terminal window and typing 'telnet 127.0.0.1 6780'. Telnet should open a connection to the server and whatever you type should be echoed back to you (and displayed on the server window, since we started it in verbose mode!) Quit telnet by typing ctrl-] (will bring up a 'telnet>' prompt) and typing 'quit'. End the telnet window's terminal session by typing 'exit'; when it says process completed it's safe to close that window.
  8. To close the server, select the terminal window with the socketserver process running in it and hit ctrl-c. You will be taken back to a terminal command line, so you can type 'exit' and close the window just like you did for the telnet window.
  9. That's all there is to it. You've started the server, talked to it, heard back from it, and shut it all down. The beauty of this server is that it doesn't really do any handling of the messages, it simply passes them on to all the clients connected to it. You can write your own protocol for all of the clients to use so they can understand each other. One protocol that I kinda like is '[TO]:[FROM]:[MESSAGE]:[PARAMETERS]'; for example, a message to change the color of ball 27 on computer2 might look like this: 'computer2:maincomputer:changecolor:ball27,red'. I'm using the : as a divider, but any character not used by your messages can define the breaks in the message. It's really up to you how the computers will talk, because the messages are written and interpreted by your client software.
  10. If you are using this for an installation, you can set the default application for socketserver.sh to Terminal, then put it in your startup items... When the installation machine is turned on, the server will launch and become available to whatever presentation software you are using for the exhibit.

socketserver.sh takes more parameters than just '-v'... Here is a list of parameters you can pass to the server when starting it up:

  • -v : turns verbose mode on; default is not verbose, messages will not show
    example: './socketserver.sh -v' starts socketserver in verbose mode
  • [ip] : sets ip address to use (if valid)
    example: './socketserver.sh 192.168.0.5' starts socketserver at address 192.168.0.5
  • -l : sets ip to use as 127.0.0.1 (localhost) (that's a lowercase L, by the way...)
    example: './socketserver.sh -l' starts socketserver at address 127.0.0.1
  • -r : sets ip address to use to an assigned or static external ip
    example: './socketserver.sh -r' queries the OS for its ip address and uses that ip
  • [port] : sets port to use (default is 6780)
    example: './socketserver.sh 5783' starts socketserver on port 5783
  • -m [#] : sets maximum number of clients that can talk to the server
    example: './socketserver.sh -m 22' allows 22 clients to connect
  • -e [# .. #]: sets eol character(s) for all messages
    example: './socketserver.sh -e 0 14' ends messages with chr(0).chr(14)
  • -c : enables client mode (requires php version 4 and a *nix OS (linux, Darwin)
    example: './socketserver.sh -c' allows keyboard input and broadcasts what is typed to all clients

All of the above parameters are case-insensitive, especially the ip address, since it should be all numbers and periods.

Just for clarification (in case you didn't pick it up yet), this is not the same type of server as something like Apache... those make a connection, take requests, generate a response, broadcast the response to the requesting client, and then break the connection. This server is more for constant communication between multiple clients, since messages go through to everyone that's connected. I guess the easiest way to describe it is through a potential application like an instant messaging system; all clients connected will get all the messages from all the other clients, and can send messages that will go to everyone. Also, since the messages are broadcasted to ALL the connected clients, some sort of protocol should be used for the messages defining who the messages are from (at the very least) and to (useful as well); that way the clients can only take action on stuff that's to them.

Important: Avoid setting up a feedback loop; if you take action on a received message that involves sending a new message, make sure that the response won't trigger a new response... for example,

Your application: 'if I get a message of "OK" send a message of "OK"'

This example would cause your client to repeatedly respond to itself, bringing the server to a grinding halt. This example would work if the recommendation to use a 'to' and 'from' is implemented:

Your application: 'if a message is not addressed from me and says "OK" send a message of "OK" to everybody from me'

Here's the download link one more time...
socketserver version 1