如何用 Perl 实现一个简单的 IRC 客户端?

发布于 2024-09-26 02:48:07 字数 781 浏览 9 评论 0原文

我正在开发一个需要将 IRC 消息发送到内部 IRC 频道的工具。这不是一个持续运行的程序,而是一个偶尔被调用的工具,并且需要能够在调用时用几条消息通知通道。

我查看了 Net::IRC,但它自 2004 年以来就已经死了。所以我查看了它列出的替代方案(Bot::BasicBotPOE::Component::IRC),但这两个都需要在POE 及其事件循环。对于 Net::Async::IRC 因为它需要在 IO::Async 事件循环中运行。

我不是在编写一个需要与任何东西交互的成熟机器人,我只是想登录到 irc 服务器,加入频道,发布一些快速消息,然后离开。我不想为了做到这一点而必须重新编写整个程序以适应某些框架的事件循环。

那么,对于简单 IRC 客户端的库有什么建议,并且不会让我重写整个应用程序吗?

I'm working on a tool that needs to send IRC messages to an internal IRC channel. This isn't a constantly running program, but rather a tool that will be invoked occasionally and needs to be able to notify the channel with a couple of messages when it's invoked.

I looked at Net::IRC, but it's been dead since 2004. So I looked at the alternatives that it lists (Bot::BasicBot and POE::Component::IRC) but both of those need to be run under POE and its event loop. The same problem occurs for something like Net::Async::IRC since it needs to be run in the IO::Async event loop.

I'm not writing a full fledged bot that needs to interact with anything, I just want to login to an irc server, join a channel, post some quick messages and then leave. I don't want to have to re-write this whole program to fit inside of some framework's event loop just to do this.

So, any recommendations for a library for a simple IRC client that won't make me rewrite my whole app?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

狠疯拽 2024-10-03 02:48:07

使用 AnyEvent::IRC::Client,同时使用 AnyEvent“事件循环” ,您不必重写您的应用程序即可使用它,您可以执行以下操作:

use AnyEvent;
use AnyEvent::IRC::Client;

与模块的其余部分一起使用行;和类似的东西

sub do_irc {
    my $log_chan = '#foobar';
    my $timer; 
    my $c = AnyEvent->condvar;
    my $con = new AnyEvent::IRC::Client;

    $con->reg_cb( join => sub {
        my ($con, $nick, $channel, $is_myself) = @_; 
        if ($is_myself && $channel eq $log_chan) {
           $con->send_chan( $channel, PRIVMSG => ($channel, 'my information') );
           $timer = AnyEvent->timer ( 
                after => 1,
                cb => sub {
                    undef $timer;
                    $con->disconnect('done');
                });
        }
    });

    $con->connect($irc_serv, 6667, { nick => $your_nick } );
    $con->send_srv( JOIN => ($log_chan) );
    $c->wait;
    $con->disconnect;

}

来进行连接,它只会在完成后返回(为简洁起见,省略了错误处理)。您的应用程序中没有其他内容需要使用 AnyEvent。

Use AnyEvent::IRC::Client, while it is using the AnyEvent 'event loop', you don't have to rewrite your app to use it, you can do something like this:

use AnyEvent;
use AnyEvent::IRC::Client;

with the rest of your module use lines; and something like this

sub do_irc {
    my $log_chan = '#foobar';
    my $timer; 
    my $c = AnyEvent->condvar;
    my $con = new AnyEvent::IRC::Client;

    $con->reg_cb( join => sub {
        my ($con, $nick, $channel, $is_myself) = @_; 
        if ($is_myself && $channel eq $log_chan) {
           $con->send_chan( $channel, PRIVMSG => ($channel, 'my information') );
           $timer = AnyEvent->timer ( 
                after => 1,
                cb => sub {
                    undef $timer;
                    $con->disconnect('done');
                });
        }
    });

    $con->connect($irc_serv, 6667, { nick => $your_nick } );
    $con->send_srv( JOIN => ($log_chan) );
    $c->wait;
    $con->disconnect;

}

to do the connection, it will only return once it is done (error handling left out for brevity). Nothing else in your app needs to use AnyEvent.

半边脸i 2024-10-03 02:48:07

Net::IRC 仍然完全可用,如果您想做的只是像您描述的那样简单的事情,我认为它会做得很好。

也就是说,习惯 POE 根本不是一个坏主意,特别是因为 IRC 机器人的功能往往会随着时间的推移而增长:)

Net::IRC is still perfectly usable, if all you want to do is something as simple as you're describing, I think it would do just fine.

That said, getting used to POE isn't a bad idea at all, especially since IRC bots tend to grow in functionality over time :)

不甘平庸 2024-10-03 02:48:07

请注意,实际上没有什么可以阻止您使用 PoCo-IRC 或 BasicBot。是的,它们在 POE 下运行,但 POE 无法控制您的整个应用程序。

如果您只是连接,在 IRC 上做一些事情,断开连接,以及做其他事情,您可以确保 IRC 会话在完成后自行销毁 - 当没有剩余会话时, POE::Kernel ->run 会将控制权返回给您的程序。

如果您正在处理寿命较长的连接,但仍想扭转控制,POE 提供了 run_one_timeslicerun_while 方法,可让您精细控制何时和何时POE 运行的地方。当然,您必须安排它至少足够频繁地运行,以响应任何服务器 PING 并防止套接字缓冲区被填满。

实际上,Net::IRC 在用自己的事件循环接管您的应用程序时做了完全相同的事情——除了它不是像 POE 或 AnyEvent 这样的命名事物——它只是“Net::IRC 事件循环”。这并不意味着您需要完全重写才能使用 Net::IRC,也不意味着您需要完全重写才能使用 POE :)

Note that there's actually nothing stopping you from using PoCo-IRC or BasicBot. Yes, they run under POE, but POE doesn't have to have control over your entire app.

If you're just connecting, doing some stuff on IRC, disconnecting, and doing other things, you can just make sure that the IRC session destroys itself when it's done -- when there are no sessions remaining, POE::Kernel->run will return control right back to your program.

If you're dealing with a longer-lived connection, but you still want to turn the control around, POE provides run_one_timeslice and run_while methods that give you fine control over when and where POE runs. Of course, you have to arrange for it to run at least often enough to respond to any server PINGs and keep the socket buffers from filling up.

Actually, Net::IRC does exactly the same thing in taking over your app with its own event loop -- except it's not a named thing like POE or AnyEvent -- it's just "the Net::IRC event loop". It doesn't mean you need a total rewrite to work with Net::IRC, and it doesn't mean you need a total rewrite to work with POE :)

勿忘心安 2024-10-03 02:48:07

使用 MkV 的答案,我能够创建一个有效的命令行脚本:

#!/usr/bin/perl

use strict;
use warnings;
use AnyEvent;
use AnyEvent::IRC::Client;
use Data::Dumper ();
use Getopt::Long;

my %opt = (
    channel => '#ircmsgtest',
    nick    => "ircmsg$",
    port    => 6667,
    server  => 'irc.freenode.net',
    verbose => undef,
);

GetOptions(\%opt,'channel','nick', 'port', 'server', 'verbose|v');
my $message = shift() || "test message @{[ scalar localtime() ]}";
if ($opt{verbose}) {
    warn "message is: '$message'";
    warn Data::Dumper->Dump([\%opt], [qw(*opt)]);
}

my $c = AnyEvent->condvar;
my $con = AnyEvent::IRC::Client->new;

$con->reg_cb(
    join => sub {
        my ($con, $nick, $channel, $is_myself) = @_; 
        if ($is_myself && $channel eq $opt{channel}) {
            $con->send_chan($channel, PRIVMSG => $channel, $message);
            $c->send;
        }
    }
);

$con->connect($opt{server}, $opt{port}, { nick => $opt{nick} } );
$con->send_srv(JOIN => $opt{channel});
$c->wait;
$con->disconnect;

它连接、发送消息,然后断开连接,这非常适合的需求。

Using the answer from MkV, I was able to create a working command-line script:

#!/usr/bin/perl

use strict;
use warnings;
use AnyEvent;
use AnyEvent::IRC::Client;
use Data::Dumper ();
use Getopt::Long;

my %opt = (
    channel => '#ircmsgtest',
    nick    => "ircmsg$",
    port    => 6667,
    server  => 'irc.freenode.net',
    verbose => undef,
);

GetOptions(\%opt,'channel','nick', 'port', 'server', 'verbose|v');
my $message = shift() || "test message @{[ scalar localtime() ]}";
if ($opt{verbose}) {
    warn "message is: '$message'";
    warn Data::Dumper->Dump([\%opt], [qw(*opt)]);
}

my $c = AnyEvent->condvar;
my $con = AnyEvent::IRC::Client->new;

$con->reg_cb(
    join => sub {
        my ($con, $nick, $channel, $is_myself) = @_; 
        if ($is_myself && $channel eq $opt{channel}) {
            $con->send_chan($channel, PRIVMSG => $channel, $message);
            $c->send;
        }
    }
);

$con->connect($opt{server}, $opt{port}, { nick => $opt{nick} } );
$con->send_srv(JOIN => $opt{channel});
$c->wait;
$con->disconnect;

It connects, sends the message, and then disconnects, which is perfect for my needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文