D
deadpickle
I am trying to build a chat client that uses IRC and is built in the
framework of Gtk2. So far it works well but not great. Right now the
client connects to a server and joins a channel. Also, the client can
send messages to the channel and amazingly they are received on the
channel. The problem I am encountering is that the chat client is not
receiving all the raw lines sent by the IRC server (for an example of
what I mean try this script: http://www.oreilly.com/pub/h/1964). If it
is not receiving all the lines then it can only send messages not
receive them. So I am looking for help on how I can get the program to
receive messages so that they can be displayed in the window.
#!/usr/local/bin/perl -w
use strict;
use Gtk2 '-init';
use Glib qw/TRUE FALSE/;
use IO::Socket;
#-------------------Shared Variables-------------------
my $server = "irc.freenode.net";
my $nick = "simple";
my $login = "simple";
my $channel = "#GRRUVI";
my $sock;
#-------------------Main Loop-------------------
my $window = Gtk2::Window->new('toplevel');
$window->signal_connect( delete_event => sub {
close($sock);
Gtk2->main_quit;
});
$window->set_default_size( 300, 200 );
my $table = Gtk2::Table->new(2, 1, FALSE);
my $scroller = Gtk2::ScrolledWindow->new;
my $textview = Gtk2::TextView->new;
my $entry = Gtk2::Entry->new;
$scroller->add($textview);
$table->attach_defaults($scroller, 0, 1, 0, 1);
$table->attach_defaults($entry, 0, 1, 1, 2);
$window->add($table);
# allows for sending each line with an enter keypress
my $send_sig = $entry->signal_connect ('key-press-event' => sub {
my ($widget,$event)= @_;
if( $event->keyval() == 65293){ # a return key press
my $text = $entry->get_text;
if(defined $sock){ print $sock "PRIVMSG $channel :$text
\r\n";}
$entry->set_text('');
$entry->set_position(0);
}
});
$entry->signal_handler_block($send_sig); #not connected yet
$entry->set_editable(0);
$window->show_all;
connecting();
Glib::IO->add_watch( fileno $sock, [qw/in hup err/], \&incoming_data,
$sock );
Gtk2->main;
#-------------------Connect to Server-------------------
sub connecting {
# Connect to the IRC server.
$sock = new IO::Socket::INET(
PeerAddr => $server,
PeerPort => 6667,
Proto => 'tcp'
) or die "Can't connect\n";
# Log on to the server.
print $sock "NICK $nick\r\n";
print $sock "USER $login 8 * erl IRC Hacks Robot\r\n";
# Read lines from the server until it tells us we have connected.
while (my $input = <$sock>) {
# Check the numerical responses from the server.
if ($input =~ /004/) {
# We are now logged in.
last;
}
elsif ($input =~ /433/) {
die "Nickname is already in use.";
}
}
# Join the channel.
print $sock "JOIN $channel\r\n";
$entry->set_editable(1);
$entry->grab_focus;
$entry->signal_handler_unblock ($send_sig);
Gtk2->main_iteration while Gtk2->events_pending;
}
#-------------------Incoming data-------------------
sub incoming_data {
my ( $fd, $condition, $fh ) = @_;
if ( $condition eq 'in' ) {
my $input = scalar <$fh>;
chop $input;
# if ( defined $data ) {
# # do something useful with the text.
# my $buffer = $textview->get_buffer;
# $buffer->insert( $buffer->get_end_iter, $data );
# }
if ($input =~ /^PING(.*)$/i) {
# We must respond to PINGs to avoid being disconnected.
print $sock "PONG $1\r\n";
}
else {
# Print the raw line received by the bot.
print "$input\n";
}
}
return TRUE;
}
framework of Gtk2. So far it works well but not great. Right now the
client connects to a server and joins a channel. Also, the client can
send messages to the channel and amazingly they are received on the
channel. The problem I am encountering is that the chat client is not
receiving all the raw lines sent by the IRC server (for an example of
what I mean try this script: http://www.oreilly.com/pub/h/1964). If it
is not receiving all the lines then it can only send messages not
receive them. So I am looking for help on how I can get the program to
receive messages so that they can be displayed in the window.
#!/usr/local/bin/perl -w
use strict;
use Gtk2 '-init';
use Glib qw/TRUE FALSE/;
use IO::Socket;
#-------------------Shared Variables-------------------
my $server = "irc.freenode.net";
my $nick = "simple";
my $login = "simple";
my $channel = "#GRRUVI";
my $sock;
#-------------------Main Loop-------------------
my $window = Gtk2::Window->new('toplevel');
$window->signal_connect( delete_event => sub {
close($sock);
Gtk2->main_quit;
});
$window->set_default_size( 300, 200 );
my $table = Gtk2::Table->new(2, 1, FALSE);
my $scroller = Gtk2::ScrolledWindow->new;
my $textview = Gtk2::TextView->new;
my $entry = Gtk2::Entry->new;
$scroller->add($textview);
$table->attach_defaults($scroller, 0, 1, 0, 1);
$table->attach_defaults($entry, 0, 1, 1, 2);
$window->add($table);
# allows for sending each line with an enter keypress
my $send_sig = $entry->signal_connect ('key-press-event' => sub {
my ($widget,$event)= @_;
if( $event->keyval() == 65293){ # a return key press
my $text = $entry->get_text;
if(defined $sock){ print $sock "PRIVMSG $channel :$text
\r\n";}
$entry->set_text('');
$entry->set_position(0);
}
});
$entry->signal_handler_block($send_sig); #not connected yet
$entry->set_editable(0);
$window->show_all;
connecting();
Glib::IO->add_watch( fileno $sock, [qw/in hup err/], \&incoming_data,
$sock );
Gtk2->main;
#-------------------Connect to Server-------------------
sub connecting {
# Connect to the IRC server.
$sock = new IO::Socket::INET(
PeerAddr => $server,
PeerPort => 6667,
Proto => 'tcp'
) or die "Can't connect\n";
# Log on to the server.
print $sock "NICK $nick\r\n";
print $sock "USER $login 8 * erl IRC Hacks Robot\r\n";
# Read lines from the server until it tells us we have connected.
while (my $input = <$sock>) {
# Check the numerical responses from the server.
if ($input =~ /004/) {
# We are now logged in.
last;
}
elsif ($input =~ /433/) {
die "Nickname is already in use.";
}
}
# Join the channel.
print $sock "JOIN $channel\r\n";
$entry->set_editable(1);
$entry->grab_focus;
$entry->signal_handler_unblock ($send_sig);
Gtk2->main_iteration while Gtk2->events_pending;
}
#-------------------Incoming data-------------------
sub incoming_data {
my ( $fd, $condition, $fh ) = @_;
if ( $condition eq 'in' ) {
my $input = scalar <$fh>;
chop $input;
# if ( defined $data ) {
# # do something useful with the text.
# my $buffer = $textview->get_buffer;
# $buffer->insert( $buffer->get_end_iter, $data );
# }
if ($input =~ /^PING(.*)$/i) {
# We must respond to PINGs to avoid being disconnected.
print $sock "PONG $1\r\n";
}
else {
# Print the raw line received by the bot.
print "$input\n";
}
}
return TRUE;
}