This is a pared down sample from my CB fetch program to show how you can insert a Coro socket server into an existing Coro application. This sample uses local unix sockets, but a simple switch to the AnyEvent::Socket::tcp_server line should enable tcp sockets as well. To see this in action, simply run this app, and then from another terminal, run "socat readline /tmp/c.sock". You can then interact with it from there. In this case, entering 'a' (no quotes) will get a pair of responses (one "immediate" and another one "delayed"), 'b' will get a single response, 'exit' will close the socket, and anything else will get a confused response. Actually doing useful stuff is left as an excersise for the implementor, this is just an example.

What I may do with this is implement ambrus' vapourware. By opening a real tcp socket (through the firewall, too), I may allow people to connect to my fetch app, and request recent messages (I'm not going to allow querying of the entire db, maybe just the last hour), as well as get cb messages "pushed" through the connection (as opposed to the "pull" that I currently do). CB apps could be written around this, allowing them to prepopulate with recent messages rather than missing everything that has gone before.

#!/usr/bin/perl use 5.14.1; use EV; use Coro; use Coro::Handle; use AnyEvent::Socket; use Guard; my $channel = Coro::Channel->new(); sub handle_server { my $fh = shift; # handle input. async_pool { while (defined $fh and defined (my $line = $fh->readline())) { chomp $line; given($line) { when('a') { $channel->put("message A"); # this will print se +cond $fh->print("you said 'a'\n"); # this will print fi +rst } when ('b') { $fh->print("you said 'b'\n"); } when ('exit') { $fh->print("Bye!\n"); $channel->shutdown(); $fh = undef; last; } default { $fh->print("What does '$line' mean?"); } } } }; while (my $msg = $channel->get()) { last unless $fh->print("$msg\n"); } } unlink '/tmp/c.sock'; # just in case AnyEvent::Socket::tcp_server 'unix/', '/tmp/c.sock', sub { my $fh = shift; $fh = unblock $fh; async_pool { handle_server($fh); }; return; }; # just some data... putting in the data even when there's no listeners +? # not good - but good enough for a demo. my $f = do { my $i = 0; EV::periodic 0, 1, 0, sub { $channel->put(++$i); } }; EV::loop;
Note that I'm thinking of putting every message that needs to go to the client through the Coro::Channel object - thus only a single thread does input and a single thread does output.

What advantage does this have over threading? By itself, not much. As I have more clients, maybe a bit more. And if you already have a coro environment, this fits quite nicely :-)