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

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.

Replies are listed 'Best First'.
Re^5: Perl an array of sockets
by roboticus (Chancellor) on Nov 21, 2017 at 16:21 UTC

    suhijo:

    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.

    ...roboticus

    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,

      $users{$uexten}=$cgi->{websocket};

      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 server16.pl line 86
        Nevermind my friend... for some reason the hash had a the top a "blank reference" and the queue_msg got error and block. I was this %users ={};. Thank you so much