http://qs321.pair.com?node_id=428014

bronto has asked for the wisdom of the Perl Monks concerning the following question:

Dear brothers and sisters

Building from my few threads experiences so far, I wanted to write some notes and publish them, but I also wanted to move a little forward. I discussed with a friend of mine, that's a Java and J2ME programmer, and he'd like to help me and build a sort of client for J2ME.

Unfortunately (or luckily, as always :-) in J2ME you can't create a server socket, so the principles at the base of my simple chat client of having an application that was both an http server and client couldn't apply. Therefore, we needed a chat server and a protocol; the J2ME chat client could then connect to the chat server and keep the connection open, and all chats would flow in and out from/to that connection.

We designed a small, simple protocol and he created a server using Java. The server does the following:

I was trying to design the same server in Perl, but I am stuck.

I tried to design it using forks, but I encountered a couple of problems:

  • the server sits and accepts for incoming connections; when a new connection is made, it forks a new child to handle the new connection.
    Problem: we cannot associate the socket to the user until the user itself registers; but if it registers with the child process, how could the child inform the parent about the user name?
  • when user A wants to send to user B, it does it through the client socket it previously opened to register, and the server should deliver its message to B.
    Problem: the server should stop accepting and cycle over all its client sockets to see if they have any message to be delivered; if we timeout the accept call to do this and the list of clients is long, we could lose incoming calls. We could well use a thread here, but relying on accept timeouts would coerce me to check for new messages with a granularity of seconds, while I would like to check for new messages to deliver almost continously (say: cycle over client sockets, then sleep a couple of tenth of seconds, then restart).

Then I thought about a full thread approach, but again I hit the limitation that, in my opinion, makes perl threads more similar to a toy than a tool: the impossibility to share objects, especially if they are of the filehandle kin... This makes impossible to have an hash of (ID => SOCKET) shared between the thread that manages the incoming connections and another thread that manages the delivering of user messages, that should run in parallel with it.

My reserve of fantasy, logic and imagination is over for this week. Does anyone of you have a better idea and can try to help me?

Thanks in advance

Ciao!
--bronto


In theory, there is no difference between theory and practice. In practice, there is.