#!/usr/bin/perl # CheezyChat Client. # Implements a Term::Visual based client for the # CheezyChat sample server. You get scrollback, # input editing, input history, and a pretty # pretty face for free. # Copyright 2004 by Rocco Caputo. Free software. # Same terms as Perl itself. Have fun! use warnings; use strict; use POE qw(Component::Client::TCP); use Term::Visual; # Start the TCP client. This uses callbacks # rather than response events. POE::Component::Client::TCP->new( RemoteAddress => "127.0.0.1", RemotePort => 9999, Connected => \&setup_client, Disconnected => \&shutdown_client, ServerInput => \&handle_server_input, InlineStates => { user_input => \&handle_user_input, }, ); POE::Kernel->run(); exit; # Client has connected. Set up the terminal. sub setup_client { my ($kernel, $heap) = @_[KERNEL, HEAP]; $heap->{vt} = Term::Visual->new( Alias => "user_interface", ); $heap->{window_id} = $heap->{vt}->create_window( Window_Name => "cheezychat", Buffer_Size => 1000, # Scrollback length. History_Size => 50, # Input history size. Status_Height => 1, # Status bar height. Title => "CheezyChat Client", ); $heap->{vt}->print( $heap->{window_id}, "-----", "Welcome to the CheezyChat Client.", "In a dire emergency, ^\\ should exit.", "^P and ^N move through input history.", "Page up/down move through scrollback.", "Other keys do other things.", "-----", ); $kernel->post( "user_interface", # Tell Term::Visual "send_me_input", # ... to send me input "user_input", # ... as "user_input". ); } # Pass user input to the server. An exception # (probably ^\) has happened if the input isn't # defined. sub handle_user_input { my ($kernel, $heap) = @_[KERNEL, HEAP]; my $input = $_[ARG0]; if (defined $input) { $heap->{server}->put($input); return; } $kernel->yield("shutdown"); } # Pass server input to the user. sub handle_server_input { my ($heap, $input) = @_[HEAP, ARG0]; $heap->{vt}->print($heap->{window_id}, $input); } # Client has disconnected, either on its own or # as a result of a user interrupt. Clean up the # user interface. sub shutdown_client { my $heap = $_[HEAP]; $heap->{vt}->delete_window($heap->{window_id}); }