I’m thinking of rewriting Phoebe using Mojo::IOLoop instead of Net::Server. One problem I needed to solve was listening on different ports (e.g. 443 and 1965), for different hostnames (alexschroeder.ch, emacswiki.org, communitywiki.org, transjovian.org, toki.transjovian.org, vault.transjovian.org, next.oddmuse.org), with different TLS certificates...
This is what I had:
Mojo::IOLoop->server({port ⇒ ... , address ⇒ ... , tls ⇒ 1, tls_cert ⇒ ..., tls_key ⇒ ... } ⇒ sub { ... })
I started wondering: how can I have multiple ports, multiple addresses, and multiple TLS certs in here? Can they take arrays? The man pages was inconclusive. I looked at the source. The address and port are passed on to IO::Socket::IP. I saw something about PeerAddrInfo... and it got more and more confusing, so I asked on the Perl IRC channel.
“What on earth are you doing, and why do you believe that’s the solution? – LeoNerd
I don’t know why I often end up in these dead ends when I read the man pages for these packages.
If you want to listen on multiple ports, you use multiple servers – LeoNerd
I... I guess that makes sense!
So here’s something that works:
use Mojo::IOLoop; use Modern::Perl; # Listen on port 3000 for my $address (qw(localhost 127.0.0.2)) { for my $port (qw(79 70)) { Mojo::IOLoop->server({address => $address, port => $port} => sub { my ($loop, $stream) = @_; $stream->on(read => \&echo)})}}; sub echo { my ($stream, $bytes) = @_; # Write response $stream->write("Echo: $bytes"); $stream->close_gracefully(); } # Start event loop if necessary Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
Starting it needs sudo because the ports are below 1024: gopher is on port 70 and finger is on port 79.
sudo perl test.pl
Testing it:
$ echo alex | netcat localhost 70 Echo: alex $ echo alex | netcat localhost 79 Echo: alex $ echo alex | netcat 127.0.0.1 79 Ncat: Connection refused. $ echo alex | netcat 127.0.0.2 79 Echo: alex $ finger alex@localhost Echo: alex $ finger berta@127.0.0.1 finger: connect: Connection refused $ finger berta@127.0.0.2 Echo: berta
Yes! I think I can work with that. 🙂
#Perl