use threads; ## provides async. use Thread::Queue; ## provides inter-thread communication. use Win32::GUI(); use Net::XMPP; use feature 'say'; my $Qrecv = new Thread::Queue; ## For passing received mesgs from the client (main) thread to the gui thread. my $Qsend = new Thread::Queue; ## For passing msgs to send from the gui thread to the client thread sub timer_Timer() { while( $Qrecv->pending ) { ## if/while there are inbound messages my $text = $Qrecv->dequeue; ## dequeue them $wnd->messages->Text( $wnd->messages->Text() . $text . "\r\n" ); ## add them to the gui. } } sub send_message() { my $msg = $wnd->new_message->Text(); ## get the user input $Qsend->enqueue( $msg ); ## queue it to the client $wnd->messages->Text($wnd->messages->Text() . "[me] $msg\r\n"); ## add it to the window $wnd->new_message->Text(''); ## clear the input field } ## All the gui code lives in here and runs asynchronously to the main thread. my $thread = async { my $wnd = Win32::GUI::Window->new( -size => [320, 240] ); $wnd->AddTextfield( -name => 'messages', -size => [$wnd->ScaleWidth, 130], -pos => [0, 0], -multiline => 1 ); $wnd->AddTextfield( -name => 'new_message', -size => [$wnd->ScaleWidth, 20], -pos => [0, 140], -multiline => 1 ); $wnd->AddButton( -text => 'Send', -size => [80, 24], -pos => [$wnd->ScaleWidth / 2 - 40, 170], -onClick => \&send_message ); $wnd->Center; $wnd->Show; my $timer = $wnd->AddTimer('timer', 100); ## Check for message every 1/10th of a second Win32::GUI::Dialog(); ## process the dialog until it closes. }; my $client = new Net::XMPP::Client; $client->SetCallBacks( message => sub { my ($mid, $message) = @_; say 'message recieved'; $Qrecv->enqueue( ## queue the formated input msg to the gui thread '[' . $message->GetFrom('jid')->GetUserID . '] ' . $message->GetBody ); } ); my $result = $client->Connect( hostname => 'xmpphostname', port => '5222', timeout => 7, ssl => 0, tsl => 0 ); if ($result) { $client->AuthSend( username => 'user1', password => '123' ); } if ($client->Connected) { say 'connected to server'; } else { say 'error connecting to server: ' . $!; exit 0; } my $pres = Net::XMPP::Presence->new(); $pres->SetType('available'); $client->Send($pres); while( my $msg = $Qsend->dequeue ) { $client->MessageSend( to => 'user2@xmpphostname', type => 'chat', body => $msg ); } =comment Don't know what to do with this bit??? Is it necessary? if ($client->Connected) { $client->Connect() unless defined $client->Process(1); } else { $client->Connect() or die('cant connect'); } =cut