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

Hello everyone,
  I'm writing a Tk chat client for a chat server I'm working on. I'd like the interface to be somewhat like Tk/Perl Chatterbox Client. It will have an entry box, where the user type things in to send the the server, and a non-editable box, where information from the server is displayed. The problem that I run into with this is that I need to regularly query the server to get information. The only way that I can think of to do this is to send the program into an eternal loop, where it sleeps for a few seconds and then queries the server. I need to be able to routinely query the server and still be able to access other parts of the program.

I looked through the code for Tk/Perl Chatterbox Client and was overwhelmed by the size of it. I wasn't able to RTFM, because I couldn't find any FM to read.

-Ben Jacobs (dooberwah)
"one thing i can tell you is you got to be free"

Replies are listed 'Best First'.
Re: Querying a Server Periodically
by termix (Beadle) on Dec 27, 2001 at 21:13 UTC

    If the server and client are talking through TCP/IP and you are using sockets to implement that then you should be able to use select to detect when an event happens. You can use a time out with select.

    I believe a quick and dirty implementation could involve forking the client so that the parent handles communications (the select loop), while a child handles the user interface. The child and parent can communicate through TCP (or UNIX sockets) and the parent will be able to deal with that in the same select loop.

    client program connects to the server (fd a) client program opens the windows etc. client program forks. parent: wait for the child to connect. go into select loop (blocking) was it the server :---> paint the incoming message was it the child :---> send message to server was it the child and user wants to quit:-> shutdown (remember to kill child). child: connect to parent loop: if user types something send to parent

    Hmmmm... Inelligant I believe, but then I'm not being graded on this (am I?). Multi threading would be much better. But I don't know what that would do to Perl/Tk

    -- termix

(ichimunki) Re: Querying a Server Periodically
by ichimunki (Priest) on Dec 28, 2001 at 01:45 UTC
    This code could be adapted to a stateless protocol like HTTP for periodic server queries, I think.
    #!/usr/bin/perl -w use strict; use Tk; #set up our window and some interactive feature my $mw = Tk::MainWindow->new(); my $button = $mw->Button( -text => 'Pop', -command => sub {print "pop! +\n";} )->pack(); #set up our periodic task. #this executes faithfully every x milliseconds $mw->repeat(5000, \&waiting ); MainLoop; sub waiting { print "waiting...\n"; }
    5000 is the milliseconds amount (so it's a very big number for only 5 seconds, but you can also give number as 5 * 1000 to remind yourself and ease figuring out longer intervals. Give this small script a try, as long as you don't mind locking up the client while the updates are happening you don't have to resort to process forking like the Tk chatterbox does.
Re: Querying a Server Periodically
by Ryszard (Priest) on Dec 28, 2001 at 18:00 UTC

    Instead of client/server, why not try a master/slave relationship where the master will push the content out to each connected slave?

    Is that too much of a simplification?

    update: Another thought, even tho' the infrastructure may be trickier to set up, it would make the content management easier, as the master just pushes out all the latest content (every n seconds), rather than the slave requesting the newest content it hasnt recieved yet. On the other hand, under load there would be noticable lag between the 1st slave served and the last slaved served..

    Back to the thinking board.

    If each chat line was indexed with a sequence, the slave would then request each bit of additional content greater than the last bit recieved, less some time out period, so they dont get 5 weeks worth of chat downloaded to them.