in reply to Re^2: Perl an array of sockets
in thread Perl an array of sockets

I'm quite unclear what you mean by
unable to get ip, port and won't send message or close socket.
What is the output when you run this? Is there an Asterisk server listening at the port/ip you provided?


You can lead your users to water, but alas, you cannot drown them.

Replies are listed 'Best First'.
Re^4: Perl an array of sockets
by suhijo (Novice) on Nov 21, 2017 at 15:19 UTC

    It runs , When I open my webpage, websocket it's open... when I make a call, events are catched by eventhandler and call the subprocess "buscar_exten" but... no message is send to the clients "send($c,"mandando mensaje 1000\r\n",0)" connected to the websocket service, what I mean is the perl code at the top is similar but at least I can get the ip and port calling "peerhost()" and "peerport()" and when I open the socket in the "buscar_exten" at least close the socket, but the second code does nothing.

    I need when an event is received by eventhandler subprocess, send a message to the connected clients thru the websocket. The first perl code I use IO:Socket but harder to create websocket, second it's easier but still no luck.

    I need to create an array/hash of sockets and then when an event occurs in asterisk being able to send it thru sockets.


      I've not used EV, and don't think I've used WebSockets in perl (other than a trivial demo). I looked over your code a bit anyway, and while comparing it with the documentation, it seems to me that one problem you may be having is the bit where you're trying to send the message to all your websockets.

      Since @users already contains your array of websockets, I think you need to change:

      sub buscar_exten{ my $exten=@_[0]; my $href; my $role; my $some; print "buscando si <$exten> esta logueada-\n"; foreach my $fn (@users) { open my $fh, ">&=$fn" ;# or warn $! and die; send($fh,"evento llamada $exten\n",0) ; print "}\n"; } }

      Into something more like:

      sub buscar_exten{ my $exten=@_[0]; print "buscando si <$exten> esta logueada-\n"; my $cnt=0; for my $websock (@users) { print "Sending message to socket in slot $cnt\n"; ++$cnt; $websock->queue_msg("evento llamada $exten\n"); } }

      You'll also want to remove the websocket from your @users list when the websocket closes. Perhaps something like:

      on_close => sub { my($code) = @_; # remove websocket from active list @users = grep { $_ ne $cgi } @users; $cgi->{self} = undef; $cgi = undef; },

      (In fact, the whole $cgi->{self} bit seems to exist simply to hold the websocket open, which ought to be handled just fine by @users, so you may be able to remove the $cgi->{self} creation and clearing bits.

      Take my notes with a rather large grain of salt: I've only used WebSockets a little (in C++), but it seems odd to me that you're doing an authentication check inside the websocket's message received hook, rather than checking the authentication before bothering to create the WebSocket.


      When your only tool is a hammer, all problems look like your thumb.

        Many thanks !! it worked perfectly. too bad the module don't have the "peeraddr" like IO::Socket but I think I can take it out from http header

        As for the authentication, is just a test, the code would be inside some Oracle APEX and we are testing

        One last thing, instead of using an array I would rather use a hash to test is a user is logged in before sending,


        but an error ocurrs, like the socket is not being push into users

        for my $a ( keys %users ) { print "send to extension: $a "; my $sck=$users{$a}; $sck->queue_msg("evento llamada $exten\n"); } ....... EV: error in callback (ignoring): Can't call method "queue_msg" on an +undefined value at line 86