Home of the Squeezebox™ & Transporter® network music players.
Results 1 to 6 of 6
  1. #1
    Senior Member meep's Avatar
    Join Date
    Aug 2007
    Location
    Ireland
    Posts
    209

    Help: Implementing websockets in a plugin

    Still working on the Alexa for Squeezebox plugin and, while it's working well with a local proxy built in to the plugin, this still requires an open port and we're all aware of the risk there (even though this does not expose any LMS ports).

    Anyway, I'd hoped to implement an alternative that would not require an open port. The options are MQTT or WebSockets. I went for the later as the server side implementation in Node-Red was trivial. However, I'm running into problems building a websocket client inside my LMS plugin and wondered if anyone had encountered/solved similar or had a suggestion for an alternative ws implementation approach.

    (I have posted the remaining section to PerlMonks but thought I'd cross-post here as I might get more LMS-focused responses.)



    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.(AnyEvent is correctly installed via the lib folder in my plugin).

    The relevant section of my PERL code looks like this;

    Code:
    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);

    Code:
    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 extended 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 address 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 lines in <VirtualHost *.80>

    Code:
    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.
    Last edited by meep; 2017-03-27 at 08:17. Reason: code tags / cleanup


    ALEXA LMS SKILL: http://www.hab-tunes.com | Twitter: #habtunes
    Personal HA BLOG: http://mediaserver8.blogspot.com

    Squeezebox | Squeezebox Radio x 2 | Squeezebox Duet

  2. #2
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    19,781

    Help: Implementing websockets in a plugin

    > However, attempting to implement the same in PERL via 'AnyEvent:Socket'
    > (http://search.cpan.org/~plicease/Any...cket/Client.pm),
    > I consistently receive a 'No such device or address' error.(AnyEvent is
    > correctly installed via the lib folder in my plugin).


    You shouldn't need to install AnyEvent in your plugin, as LMS is based
    on it already. Alas I wouldn't be surprised if the version we're using
    was outdated. And if that was actually what your code was using, rather
    than yours.

    > 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;
    > }


    Aren't there dependencies for modules to support the ws protocol? Did
    you add them as well?

    --

    Michael

  3. #3
    Senior Member meep's Avatar
    Join Date
    Aug 2007
    Location
    Ireland
    Posts
    209
    Many thanks for that Michael

    I'm definitely using the current version of AnyEvent in my plugin lib folder as I can make code changes to those files and see it have an effect.

    However, it's still possible there's a conflict there somewhere. I also believe I have all the dependencies in place as initially, there were a good number of errors relating to missing files etc. but all now resolved. I will check this further though.

    Right now, my plan is to build the simple websocket client in PERL outside the LMS plugin context to see if it's an issue with the libs or the libs inside LMS. Then, I'll try removing the AnyEvent packages from my plugin folder to see if I can call back on those used in LMS.

    I'll report back on what I find.

    Peter


    ALEXA LMS SKILL: http://www.hab-tunes.com | Twitter: #habtunes
    Personal HA BLOG: http://mediaserver8.blogspot.com

    Squeezebox | Squeezebox Radio x 2 | Squeezebox Duet

  4. #4
    Senior Member meep's Avatar
    Join Date
    Aug 2007
    Location
    Ireland
    Posts
    209
    So I gave up implementing a standalone test as it's beyond my PERL abilities. However, I see that the LMS AnyEvent is at version 5.x and doesn't include the WebSockets packages. The plugin does indeed run this older version, with only the additional, newer WebSockets code running from the plugin lib folder. I don't see any way to override the older AnyEvent core packages in the LMS with the newer versions and I'd guess this would be a very bad thing in any case.

    I'll try to implement an alternative WebSockets solution with Mojolicious or some other solution that won't conflict with LMS.

    Peter


    ALEXA LMS SKILL: http://www.hab-tunes.com | Twitter: #habtunes
    Personal HA BLOG: http://mediaserver8.blogspot.com

    Squeezebox | Squeezebox Radio x 2 | Squeezebox Duet

  5. #5
    Senior Member meep's Avatar
    Join Date
    Aug 2007
    Location
    Ireland
    Posts
    209

    cc

    Looks like Websocket clients just won't work in the context of LMS.

    The obvious way would be AnyEvent::Websocket::Client but this is at version 7.x and the AnyEvent libs in LMS are at 5.x and don't include WebSocket support. Adding the WebSocket package and dependencies to my plugin lib folder works OK but attempting to construct sockets fails as described above, likely due to version conflicts.

    I also tried Mojo::Websocket and Net:;Async::Websocket but both of these seem to require their own loops and implementing causes LMS to quit :-( Couldn't get them to function at all with Slim::Networking.

    I guess I could try to build my own Websocket implementation using lower-level libs but my Perl is just not up to that.

    I'm moving on to Anyevent::MQTT which is showing a little more promise but will be more involved on the server side, unfortunately.


    ALEXA LMS SKILL: http://www.hab-tunes.com | Twitter: #habtunes
    Personal HA BLOG: http://mediaserver8.blogspot.com

    Squeezebox | Squeezebox Radio x 2 | Squeezebox Duet

  6. #6
    Senior Member meep's Avatar
    Join Date
    Aug 2007
    Location
    Ireland
    Posts
    209
    For anyone who trips across this in the future, I got MQTT working through Net::MQTT::Message and IO::Socket::INET which will co-operate with Slim::Utils::Network::blocking and Slim::Networking::Select


    ALEXA LMS SKILL: http://www.hab-tunes.com | Twitter: #habtunes
    Personal HA BLOG: http://mediaserver8.blogspot.com

    Squeezebox | Squeezebox Radio x 2 | Squeezebox Duet

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •