meep has asked for the wisdom of the Perl Monks concerning the following question:

First time poster. Learning Perl and have made good progress but I'm stumped by a problem I've encountered when attempting to implement WebSockets....

I have a WebSocket server application built in Node-Red sitting behind an Apache reverse-proxy configuration. (The server is very simple, responding only to 'Ping' commands with an 'OK' response.)

Using the 'Simple Websocket Client' extension for Google Chrome, I can successfully open the server URL, send the 'Ping' request and receive the 'OK' response, so I know that the server setup works.

However, attempting to implement the same in PERL via AnyEvent:Socket, I consistently receive a 'No such device or address' error.p>

The relevant section of my PERL code looks like this;

sub sockInit{ use AnyEvent::WebSocket::Client 0.12; use URI my $client = AnyEvent::WebSocket::Client->new( ); my $uri = URI->new('ws://mydomain.com/ws/test'); $client->connect($uri)->cb(sub { our $connection = eval { shift->recv }; if($@) { # handle error... myDebug($@); return; } # send a message through the websocket... # $connection->send('ping'); }); }

Ultimately, this fails in this section of AnyEvent/WebSocket/Client.pm (around line 90);

#AnyEvent::Socket::tcp_connect $uri->host, $uri->port, sub { AnyEvent::Socket::tcp_connect $uri->as_string, 80, sub { my $fh = shift; unless($fh) { $done->croak("unable to connect to ".$uri->as_string." $!"); return; }

(I've made some small edits there to get around issues with $uri->host and $uri->port not existing for URI::_generic which is what ws protocol comes through as. I've also extened the croak message to include the uri)

Here's what it typically generates;

unable to connect to ws://mydomain.com/ws/test No such device or addr +ess at /usr/share/squeezeboxserver/Plugins/Alexa/HabProxy.pm line 201 +.

(This code runs inside a plugin I'm writing for the Logitech SqueezeServer platform)

The relevant part of my Apache hosts config includes these libes in <VirtualHost *.80>

ProxyPass /ws ws://127.0.0.1:1880/ws ProxyPassReverse /ws ws://127.0.0.1:1880/ws

As noted, I know this to be working. Ultimately, I need this to work with user authentication in Apache against a DB and with WSS: but I've simplified extensively here to see if I can track down why my Perl implementation might be failing but it works fine in other clients.

I've learned a lot from this site so far, hopefully someone can help me out with my first problem for which my Google Fu cannot product an answer.

Replies are listed 'Best First'.
Re: AnyEvent:WebSocket produces 'No such device or address' error
by Corion (Patriarch) on Mar 27, 2017 at 15:02 UTC

    AnyEvent::Socket::tcp_connect likely only wants a hostname or an IP address, not an URI.

    Maybe you can try the following:

    AnyEvent::Socket::tcp_connect 'mydomain.com', 80, sub { my $fh = shift; unless($fh) { $done->croak("unable to connect to ".$uri->as_string." $!"); return; }

    This is somewhat the first step, because AnyEvent::Socket doesn't speak whatever protocol websockets layer on top of TCP.

      Thanks for the response. On foot of your suggestion, I've tried multiple hardcoded variants of the hostname and raw IP address there instead of the passed-in URI but to no avail.

        Maybe you can reduce your code to a short, self-contained example that we can use to reproduce your problem.

        I'm not sure where in the layers upon layers of protocol modules the problem lies, so something, maybe using AnyEvent::WebSocket that tries to access a public accessible websocket machine can help us see better what happens.

Re: AnyEvent:WebSocket produces 'No such device or address' error
by Anonymous Monk on Mar 27, 2017 at 22:38 UTC
    Use Mojolicious instead. Set up a real API that returns JSON.
    $ perl -Mojo -E 'a("/hello" => {json => {hello => 'world'}})->start' d +aemon
    Boom! xD