Re: A Gtk2 IRC Chat Client
- From: deadpickle <deadpickle@xxxxxxxxx>
- Date: Wed, 13 Feb 2008 20:43:10 -0800 (PST)
On Feb 12, 10:06 am, Ben Morrow <b...@xxxxxxxxxxxx> wrote:
Quoth deadpickle <deadpic...@xxxxxxxxx>:
I noticed a few things:
I tested the program using mIRC. I logged into the channel with the
client and under another name with mIRC. Logging in works fine, I can
see the clients nickname in the channel. What the problem seems to be
is when the MOTD is displayed. It seems that only a few lines of the
MOTD are displayed before the 'in' condition is stopped and the
message stops displaying in the terminal window. When I type in mIRC,
a line of the MOTD is displayed in terminal window. The $input
variable seems to be behind the real-time sending of the messages. I'm
not sure how to remove this lag and I'm looking for ideas.
You are reading the filehandle in buffered mode, which is not compatible
with select (which is used by Glib::IO->add_watch). Either switch to
sysread, or push a :unix layer to switch to unbuffered mode.
Ben
Yep your both right. Adding sysread corrected the problem and now I
have another question. I am trying to complete the IRC Client with
giving the user the ability to disconnect and reconnect to the IRC
server. The problem I am encountering is that when the user
disconnects the Glib::IO tries to read from the closed socket. I tried
to undefine the Glib::IO but that hasent work.
#!/usr/local/bin/perl -w
use strict;
use Gtk2 '-init';
use Glib qw/TRUE FALSE/;
use IO::Socket;
#-------------------Global Variables-------------------
my $chat_state = 'Connect';
my $sock;
my $channel;
my $nick;
my $irc;
my $chat_entry;
my $chat_send_sig;
my $chat_textview;
my $chat_button;
my $watch;
#############################################
#specials that will be input by the efault file
$channel = '#GRRUVI';
$nick = 'Lahowetz';
$irc = 'irc.freenode.net';
my $login = $nick;
#############################################
#-------------------Main Loop-------------------
&chat_build;
Gtk2->main;
#-------------------chat Build-------------------
sub chat_build {
my $chat_window = Gtk2::Window->new('toplevel');
$chat_window->set_title('Chat Client');
$chat_window->set_position('center');
$chat_window->set_default_size( 300, 200 );
$chat_window->signal_connect(delete_event=> sub{exit});
my $chat_scroll = Gtk2::ScrolledWindow->new;
$chat_textview = Gtk2::TextView->new;
$chat_entry = Gtk2::Entry->new;
my $chat_vbox = Gtk2::VBox->new;
my $chat_buffer = $chat_textview->get_buffer;
$chat_buffer->create_mark( 'end', $chat_buffer->get_end_iter,
FALSE );
$chat_buffer->signal_connect(insert_text => sub {
$chat_textview->scroll_to_mark( $chat_buffer->get_mark('end'),
0.0, TRUE, 0, 0.5 );
});
$chat_button = Gtk2::Button->new;
$chat_button->set_label($chat_state);
$chat_scroll->add($chat_textview);
$chat_vbox->add($chat_scroll);
$chat_vbox->pack_start( $chat_entry, FALSE, FALSE, 0 );
$chat_vbox->pack_start( $chat_button, FALSE, FALSE, 0 );
$chat_window->add($chat_vbox);
# allows for sending each line with an enter keypress
$chat_send_sig = $chat_entry->signal_connect ('key-press-event' =>
sub {
my ($widget,$event)= @_;
if( $event->keyval() == 65293){ # a return key press
my $text = $chat_entry->get_text;
if(defined $sock){ print $sock "PRIVMSG $channel :$text
\r\n";}
$chat_entry->set_text('');
$chat_entry->set_position(0);
post($nick, $text);
}
});
$chat_entry->signal_handler_block($chat_send_sig); #not connected
yet
$chat_entry->set_editable(0);
$chat_textview->set_editable(0);
$chat_textview->set_cursor_visible(0);
$chat_window->show_all;
$chat_button->signal_connect("clicked" => sub {
if ($chat_state eq 'Connect') {
$chat_button->set_label('Disconnect');
$chat_state='Disconnect';
connecting();
}
else {
$chat_button->set_label('Connect');
$chat_state='Connect';
close $sock;
undef $watch;
}
});
return;
}
#-------------------Connect to IRC Server-------------------
sub connecting {
# Connect to the IRC server.
$sock = new IO::Socket::INET(
PeerAddr => $irc,
PeerPort => 6667,
Proto => 'tcp',
) or die "Can't connect\n";
if (defined $sock){
my $sys_msg = "Connected to $irc ...";
post($nick, $sys_msg);
}
# Log on to the server.
print $sock "NICK $nick\r\n";
print $sock "USER $login 8 * :Just a Tester\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.
my $sys_msg = "Logged in to $irc ...";
post($nick, $sys_msg);
print $sock "JOIN $channel\r\n";
$watch = Glib::IO->add_watch( fileno $sock, [qw/in hup
err/], \&incoming_data, $sock );
$chat_entry->set_editable(1);
$chat_entry->grab_focus;
$chat_entry->signal_handler_unblock ($chat_send_sig);
last;
}
elsif ($input =~ /433/) {
my $sys_msg = "Nickname is already in use";
post($nick, $sys_msg);
$chat_state = 'Connect';
$chat_button->set_label($chat_state);
$chat_entry->signal_handler_block($chat_send_sig);
close $sock;
last;
}
}
Gtk2->main_iteration while Gtk2->events_pending;
}
#-------------------Watch for IRC Inputs-------------------
sub incoming_data {
my ( $fd, $condition, $fh ) = @_;
if ( $condition eq 'in' ) {
my $input;
sysread $fh, $input, 1000000;
chop $input;
if ($input =~ /^PING(.*)$/i) {
# We must respond to PINGs to avoid being disconnected.
print $sock "PONG $1\r\n";
}
if ($input =~ m/PRIVMSG\s($channel)/) {
print "$input\n";
my @sender = split(/!/, $input);
my @message = split(/:/, $input);
my $length = length($sender[0]);
my $who = substr($sender[0], 1, $length);
post($who, $message[2]);
}
if ($input =~ m/QUIT/) {
print "$input\n";
my @sender = split(/!/, $input);
my $length = length($sender[0]);
my $who = substr($sender[0], 1, $length);
my $sys_msg = "$who has QUIT!";
post($who, $sys_msg);
}
if ($input =~ m/JOIN/) {
print "$input\n";
my @sender = split(/!/, $input);
my $length = length($sender[0]);
my $who = substr($sender[0], 1, $length);
my $sys_msg = "$who has JOINED $channel!";
post($who, $sys_msg);
}
else {
# Print the raw line received by the bot.
print "$input\n";
}
}
return TRUE;
}
#-------------------Post messages in the Window-------------------
sub post{
my ($name, $msg) = @_;
my $chat_buffer = $chat_textview->get_buffer;
$chat_buffer->insert( $chat_buffer->get_end_iter, "$name: $msg
\n" );
}
.
- Follow-Ups:
- Re: A Gtk2 IRC Chat Client
- From: zentara
- Re: A Gtk2 IRC Chat Client
- References:
- A Gtk2 IRC Chat Client
- From: deadpickle
- Re: A Gtk2 IRC Chat Client
- From: deadpickle
- Re: A Gtk2 IRC Chat Client
- From: Ben Morrow
- A Gtk2 IRC Chat Client
- Prev by Date: Re: Fast checksums?
- Next by Date: Re: Newbie question
- Previous by thread: Re: A Gtk2 IRC Chat Client
- Next by thread: Re: A Gtk2 IRC Chat Client
- Index(es):
Relevant Pages
|