Asynchronous WebSocket client

Overview

Pawl

Autobahn Testsuite CI status

An asynchronous WebSocket client in PHP

Install via composer:

composer require ratchet/pawl

Usage

Pawl as a standalone app: Connect to an echo server, send a message, display output, close connection:

close(); }); $conn->send('Hello World!'); }, function ($e) { echo "Could not connect: {$e->getMessage()}\n"; }); ">


require __DIR__ . '/vendor/autoload.php';

\Ratchet\Client\connect('wss://echo.websocket.org:443')->then(function($conn) {
    $conn->on('message', function($msg) use ($conn) {
        echo "Received: {$msg}\n";
        $conn->close();
    });

    $conn->send('Hello World!');
}, function ($e) {
    echo "Could not connect: {$e->getMessage()}\n";
});

Classes

There are 3 primary classes to be aware of and use in Pawl:

Connector:

Makes HTTP requests to servers returning a promise that, if successful, will resolve to a WebSocket object. A connector is configured via its constructor and a request is made by invoking the class. Multiple connections can be established through a single connector. The invoke mehtod has 3 parameters:

  • $url: String; A valid uri string (starting with ws:// or wss://) to connect to (also accepts PSR-7 Uri object)
  • $subProtocols: Array; An optional indexed array of WebSocket sub-protocols to negotiate to the server with. The connection will fail if the client and server can not agree on one if any are provided
  • $headers: Array; An optional associative array of additional headers requests to use when initiating the handshake. A common header to set is Origin
WebSocket:

This is the object used to interact with a WebSocket server. It has two methods: send and close. It has two public properties: request and response which are PSR-7 objects representing the client and server side HTTP handshake headers used to establish the WebSocket connection.

Message:

This is the object received from a WebSocket server. It has a __toString method which is how most times you will want to access the data received. If you need to do binary messaging you will most likely need to use methods on the object.

Example

A more in-depth example using explicit interfaces: Requesting sub-protocols, and sending custom headers while using a specific React Event Loop:

close(); }); $conn->on('close', function($code = null, $reason = null) { echo "Connection closed ({$code} - {$reason})\n"; }); $conn->send('Hello World!'); }, function(\Exception $e) use ($loop) { echo "Could not connect: {$e->getMessage()}\n"; $loop->stop(); }); ">


require __DIR__ . '/vendor/autoload.php';

$reactConnector = new \React\Socket\Connector([
    'dns' => '8.8.8.8',
    'timeout' => 10
]);
$loop = \React\EventLoop\Loop::get();
$connector = new \Ratchet\Client\Connector($loop, $reactConnector);

$connector('ws://127.0.0.1:9000', ['protocol1', 'subprotocol2'], ['Origin' => 'http://localhost'])
->then(function(\Ratchet\Client\WebSocket $conn) {
    $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
        echo "Received: {$msg}\n";
        $conn->close();
    });

    $conn->on('close', function($code = null, $reason = null) {
        echo "Connection closed ({$code} - {$reason})\n";
    });

    $conn->send('Hello World!');
}, function(\Exception $e) use ($loop) {
    echo "Could not connect: {$e->getMessage()}\n";
    $loop->stop();
});
Comments
  • Can't seem to connect to any websocket server

    Can't seem to connect to any websocket server

    Hey there, using latest version (v0.2.2) and can't seem to connect to any websocket server at all.

    Tried using echo.socketo.me:9000 and echo.websocket.org (using the first example on the README.md of this repo).

    Most of the times I've tried I've just got no output from the console although twice I did get this outputting on the console:

    Could not connect: HTTP/1.1 200 OK
    Date: Fri, 12 Aug 2016 20:04:59 GMT
    Server: Apache
    Last-Modified: Mon, 19 Oct 2015 15:08:14 GMT
    ETag: "222-dbe-5227683b37091"
    Accept-Ranges: bytes
    Content-Length: 3518
    Connection: close
    Content-Type: text/html; charset=UTF-8
    

    (Pretty sure that the server I connected with when that outputted does not run Apache at all which is confusing)

    I've tried on another computer, using a different Internet connection and didn't work. Although I can connect to them using my browser's built-in client and also Python so I am sure the issue is with Pawl.

    Using PHP7 - can provide extra info if required.

    Thanks.

    opened by Akhawais 16
  • Another SSL question

    Another SSL question

    $loop = React\EventLoop\Factory::create();
    $reactConnector = new React\Socket\Connector($loop, [
    	],
    	[
    	'allow_self_signed' => true, 
    	'verify_peer'       => false,
    	'verify_peer_name'  => false
    	]
    	);
    $connector = new Ratchet\Client\Connector($loop, $reactConnector);
    
    $connector('wss://'.$ip.':'.$socketPort, [], ['Origin' => 'http://localhost'])
    ->then(function(Ratchet\Client\WebSocket $conn) {
        $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
            echo "Received: {$msg}\n";
            $conn->close();
        });
    
        $conn->on('close', function($code = null, $reason = null) {
            echo "Connection closed ({$code} - {$reason})\n";
        });
    
        $conn->send('Hello World!');
    }, function(\Exception $e) use ($loop) {
        echo "Could not connect: {$e->getMessage()}\n";
        $loop->stop();
    });
    
    $loop->run();
    

    Result: Could not connect: Unable to complete SSL/TLS handshake: stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed

    Running on PHP 7.2

    The actual socket I try to connect to is running on the same server and is a very well working Ratchet socket with valid domain certificates. I'm not sure what SSL settings I should pass on.

    And yes, I read all the other SSL topics ;)

    opened by MrMoronIV 11
  • why is connect function always executed as last instruction?

    why is connect function always executed as last instruction?

    Hello, I'm trying to send multiple WS messages during a long procedure (30 to 60 seconds). Calls to connect function were put in different places but what I notice is that they are all executed as last instructions of my procedure, so what I get is a bunch of messages sent at the end of the procedure.

    Is it supposed to work this way? Should I use Threads to avoid it?

    Thanks!

    opened by sangio90 10
  • Pawl closing connection with code 1006 instead of 1000

    Pawl closing connection with code 1006 instead of 1000

    When I try to close the websocket connection with a close code 1000 (close normal), then Pawl instead disconnects with a close code 1006 (close abnormal). I've found this issue while fiddling with the Discord API and the bot account still stayed online as opposed of showing as offline. So I've fiddled a simple Node.js websocket server which dumps the close code.

    PHP code:

    $loop = \React\EventLoop\Factory::create();
    
    $connector = new \Ratchet\Client\Connector($loop);
    $connector('ws://localhost:8080')->done(function (\Ratchet\Client\WebSocket $conn) use ($loop) {
        $conn->on('message', function ($message) {
            var_dump($message);
        });
        $conn->on('close', function (...$args) {
            var_dump($args);
        });
        
        $loop->addTimer(10, function () use ($conn) {
            echo 'Closing WS'.PHP_EOL;
            $conn->close();
        });
    });
    
    $loop->run();
    

    JS code:

    const { Server } = require('ws');
    const wss = new Server({ port: 8080 });
    
    wss.on('connection', function connection(ws) {
        ws.on('close', (event) => {
            console.log('close', event);
        });
    });
    

    Logged gets the following:

    PHP:

    Closing WS
    array(3) {
      [0] =>
      int(1000)
      [1] =>
      string(0) ""
      [2] =>
      class Ratchet\Client\WebSocket#49 (6) {
        public $request =>
        class GuzzleHttp\Psr7\Request#34 (7) {
          private $method =>
          string(3) "GET"
          private $requestTarget =>
          NULL
          private $uri =>
          class GuzzleHttp\Psr7\Uri#35 (7) {
            ...
          }
          private $headers =>
          array(7) {
            ...
          }
          private $headerNames =>
          array(7) {
            ...
          }
          private $protocol =>
          string(3) "1.1"
          private $stream =>
          class GuzzleHttp\Psr7\Stream#89 (7) {
            ...
          }
        }
        public $response =>
        class GuzzleHttp\Psr7\Response#55 (6) {
          private $reasonPhrase =>
          string(19) "Switching Protocols"
          private $statusCode =>
          int(101)
          private $headers =>
          array(3) {
            ...
          }
          private $headerNames =>
          array(3) {
            ...
          }
          private $protocol =>
          string(3) "1.1"
          private $stream =>
          class GuzzleHttp\Psr7\Stream#59 (7) {
            ...
          }
        }
        protected $_stream =>
        class React\Socket\Connection#63 (6) {
          public $unix =>
          bool(false)
          public $encryptionEnabled =>
          bool(false)
          public $stream =>
          resource(61) of type (stream)
          private $input =>
          class React\Stream\DuplexResourceStream#64 (9) {
            ...
          }
          protected $listeners =>
          array(3) {
            ...
          }
          protected $onceListeners =>
          array(0) {
            ...
          }
        }
        protected $_close =>
        class Closure#42 (3) {
          public $static =>
          array(2) {
            ...
          }
          public $this =>
                  ...
    
          public $parameter =>
          array(2) {
            ...
          }
        }
        protected $listeners =>
        array(2) {
          'message' =>
          array(1) {
            ...
          }
          'close' =>
          array(1) {
            ...
          }
        }
        protected $onceListeners =>
        array(0) {
        }
      }
    }
    

    JS:

    close 1006
    

    I believe this is an issue with ratchetphp/rfc6455, but I thought I will post this issue in ratchetphp/pawl, as this is the library I use. Feel free to open an issue in rfc6455 and reference this issue. I will try digging some deeper into this issue.

    bug 
    opened by ghost 10
  • Ratchet\\Client\\Factory::Ratchet\\Client\\{closure}() must be an instance of React\\Stream\\Stream, instance of React\\SocketClient\\SecureStream given

    Ratchet\\Client\\Factory::Ratchet\\Client\\{closure}() must be an instance of React\\Stream\\Stream, instance of React\\SocketClient\\SecureStream given

    PHP Catchable fatal error:  Argument 1 passed to Ratchet\Client\Factory::Ratchet\Client\\{closure}() must be an instance of 
    React\Stream\Stream, instance of React\SocketClient\SecureStream given, 
    called in FulfilledPromise.php on line 24 and defined
    

    Anyone know what this might be? I'm with an online application and could not understand.

    bug 
    opened by hugohenrique 10
  • Connection closed (1009 - ) FRAME::CLOSE_TOO_BIG     = 1009

    Connection closed (1009 - ) FRAME::CLOSE_TOO_BIG = 1009

    I'm excited to be using Pawl, and I have it working for small files (such as 350 KB).

    However, when I send a larger file (say, 30 MB) via $fullFileName as shown below, I get this error: Connection closed (1009 - ).

    \Ratchet\Client\connect($url)->then(function(\Ratchet\Client\WebSocket $conn) use($contentType, $fullFileName) {
        $conn->on('message', function($msg) use ($conn) {
            Log::debug("Received: {$msg}");
        });
        $conn->on('close', function($code = null, $reason = null) {
            Log::debug("Connection closed ({$code} - {$reason})");
        });
        $conn->send(json_encode([
            'content-type' => $contentType,
            'timestamps' => true,
            'speaker_labels' => true,
            'smart_formatting' => true,
            'inactivity_timeout' => 60 * 5,
            'x-watson-learning-opt-out' => true,
            'action' => 'start'
        ]));
    
        $frame = new \Ratchet\RFC6455\Messaging\Frame(file_get_contents($fullFileName), true, \Ratchet\RFC6455\Messaging\Frame::OP_BINARY);
        $binaryMsg = new \Ratchet\RFC6455\Messaging\Message();
        $binaryMsg->addFrame($frame);
        $conn->send($binaryMsg);
        $conn->send(json_encode([
            'action' => 'stop'
        ]));
    }, function ($e) {
        echo "Could not connect: {$e->getMessage()}\n";
    });
    

    When I search for usages of Frame::CLOSE_TOO_BIG, I see that it's only ever used by \Ratchet\RFC6455\Messaging\CloseFrameChecker.

    But I've been unable to figure out how \Ratchet\RFC6455\Messaging\CloseFrameChecker works and what the file size limits are and how to send large files.

    I've tried first splitting my file into chunks using str_split and then adding individual frames, but then I hit session timeouts every time, even for small files.

    What is the appropriate way to send larger files, avoiding the Frame::CLOSE_TOO_BIG 1009 error and session timeouts?

    opened by ryancwalsh 8
  • Unable to establish SSL connection with Pawl

    Unable to establish SSL connection with Pawl

    Hi again, cboden. I'm having issues connecting to wss:// sockets with Pawl on a new machine. I've been banging my head against this for about 6 hours now to no avail.

    I'm starting with a brand new install of Pawl, using the test script provided, connecting to "wss://echo.websocket.org":

    <?php
    
        require __DIR__ . '/vendor/autoload.php';
    
        $loop = React\EventLoop\Factory::create();
        $connector = new Ratchet\Client\Factory($loop);
    
        $connector('wss://echo.websocket.org')->then(function(Ratchet\Client\WebSocket $conn) {
            $conn->on('message', function($msg) {
                echo "Received: {$msg}\n";
            });
    
            $conn->send('Hello World!');
        }, function($e) use ($loop) {
            echo "Could not connect: {$e->getMessage()}\n";
            $loop->stop();
        });
    
        $loop->run();
    

    composer deets:

    [slowbro@slowbro test]$ cat composer.json
    {
        "require" : {
            "ratchet/pawl": "dev-master"
        }
    }
    
    [slowbro@slowbro test]$ composer show -i
    cboden/ratchet           v0.3.2             PHP WebSocket library
    evenement/evenement      v2.0.0             Ãvénement is a very simple event dispatching library for PHP
    guzzle/common            v3.9.2             Common libraries used by Guzzle
    guzzle/http              v3.9.2             HTTP libraries used by Guzzle
    guzzle/parser            v3.9.2             Interchangeable parsers used by Guzzle
    guzzle/stream            v3.9.2             Guzzle stream wrapper component
    ratchet/pawl             dev-master 3ba8d56 Asynchronous WebSocket client
    react/cache              v0.4.0             Async caching.
    react/dns                v0.4.1             Async DNS resolver.
    react/event-loop         v0.4.1             Event loop abstraction layer that libraries can use for evented I/O.
    react/promise            v2.2.0             A lightweight implementation of CommonJS Promises/A for PHP
    react/socket             v0.4.2             Library for building an evented socket server.
    react/socket-client      v0.4.3             Async connector to open TCP/IP and SSL/TLS based connections.
    react/stream             v0.4.2             Basic readable and writable stream interfaces that support piping.
    symfony/event-dispatcher v2.6.7             Symfony EventDispatcher Component
    symfony/http-foundation  v2.6.7             Symfony HttpFoundation Component
    symfony/routing          v2.6.7             Symfony Routing Component
    

    php deets

    [slowbro@slowbro test]$ php -v
    PHP 5.6.8 (cli) (built: Apr 16 2015 14:54:09)
    Copyright (c) 1997-2015 The PHP Group
    Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
        with Xdebug v2.3.2, Copyright (c) 2002-2015, by Derick Rethans
    [slowbro@slowbro test]$ php -m
    [PHP Modules]
    bz2
    calendar
    Core
    ctype
    curl
    date
    dom
    ereg
    exif
    fileinfo
    filter
    ftp
    gettext
    hash
    iconv
    json
    libxml
    mbstring
    mhash
    mysql
    mysqli
    mysqlnd
    openssl
    pcntl
    pcre
    PDO
    pdo_mysql
    pdo_sqlite
    Phar
    posix
    readline
    Reflection
    session
    shmop
    SimpleXML
    sockets
    SPL
    sqlite3
    standard
    sysvmsg
    sysvsem
    sysvshm
    tokenizer
    wddx
    xdebug
    xml
    xmlreader
    xmlwriter
    xsl
    zip
    zlib
    
    [Zend Modules]
    Xdebug
    

    OS deets

    [slowbro@slowbro test]$ uname -a
    Linux slowbro.org 2.6.32-431.29.2.el6.x86_64 #1 SMP Tue Sep 9 21:36:05 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
    [slowbro@slowbro test]$ cat /etc/redhat-release
    CentOS release 6.6 (Final)
    [slowbro@slowbro test]$ openssl version
    OpenSSL 1.0.1e-fips 11 Feb 2013
    

    What seems to happen is that when connecting, it just hangs. like so..

    # USING ws://
    [slowbro@slowbro test]$ php test.php
    Received: Hello World!
    ^C
    
    # USING wss://
    [slowbro@slowbro test]$ php test.php
    #... HANGS FOREVER WITHOUT OUTPUT ...
    
    I'm at a complete loss here. From my debugging it looks like the steam_get_contents in vendor/react/socket-client/src/SecureStream.php handleData is blocking.. but the stream is set to be nonblocking?
    
    I'm so confuse-frustrated :(
    
    bug React 
    opened by slowbro 8
  • How to throw in rejected connect handler

    How to throw in rejected connect handler

    Hello,

    i'm not able to throw inside the rejected callback of \Ratchet\Client\connect.

    \Ratchet\Client\connect('wss://not-exists.fake')->then(function($conn) {
      echo "connected!";
    }, function ($e) {
      echo $e->getMessage();
      throw $e;
    });
    

    I also tried:

    • ->done() instead of ->then()
    • without passing the error handler at all

    Oddly, if i try with wifi turned off (Network is unreachable error), i get the Exception and i can throw as well... but with a wrong domain, the reject handler fails silently.

    question 
    opened by edolix 7
  • Connecting to WSS: Unable to complete SSL/TLS handshake

    Connecting to WSS: Unable to complete SSL/TLS handshake

    I have a Websocket server that is running behind Apache that I'm able to connect to using Chrome, Safari, and Telnet just fine. However, when attempting to connect to that same server from PHP using Pawl, it's throwing an exception during the handshake:

    Unable to complete SSL/TLS handshake: stream_socket_enable_crypto(): Peer certificate CN='*.foo.bar' did not match expected CN='local.blah.foo.bar'.

    Here's my client code:

    \Ratchet\Client\connect('wss://' . WEBSOCKET_SERVER_HOST . ':' . WEBSOCKET_SERVER_PORT)
        ->then(
              function ($conn) use ($message) {
                  $conn->send($message);
              },
              function ($e) {
                  echo $e;
              }
        );
    
    opened by JimmyPruitt 7
  • Can't connect more than one websockets simultaneously

    Can't connect more than one websockets simultaneously

    Unable to connect to two or more WebSocket services simultaneously,

    The second request goes in waiting and instantly connect when first connection closes

    here is what I did

    <?php
    
        #    PHP 7.1.8 (cli) (built: Aug  1 2017 20:56:32) ( NTS MSVC14 (Visual C++ 2015) x64 )
        #    Copyright (c) 1997-2017 The PHP Group
        #    Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
        
        
        require __DIR__ . '/vendor/autoload.php';
    
    
        $websocketURLs[] = ['url' => 'wss://echo.websocket.org', 'service' => 'websocket'];
    
        $websocketURLs[] = ['url' => 'ws://echo.socketo.me:9000', 'service' => 'socketo'];
    
    
        foreach( $websocketURLs as $v ){
        
            connect_to_websocket ( $v['url'], $v['service'] );
    
        }
    
        
        function connect_to_websocket ( &$url, &$service){
    
            $responseCount = 0;
    
            echo "\nOK... Will connect to $url at $service\n\n";
    
       
            \Ratchet\Client\connect( $url )->then(function ($connection) use ( &$url, &$service, &$responseCount ) {
    
                echo "Connected to $service\n";
    
                $connection->send( "Hello" );
    
                $connection->on('message', function($message) use ($connection, &$url, &$service, &$responseCount) {
    
                    $responseCount++;
                
                    $message = (string) $message;
    
                    echo "$service - $message - Response no. $responseCount - Will disconnect at response no. 10\n";
    
                    if( $responseCount == 10)
    
                        $connection->close();
                
                    $connection->send( $message );
    
                });
    
                $connection->on('close', function($code = null, $reason = null) use ( &$url, &$service) {
    
                    echo "Websocket Connection to $service is closed ({$code} - {$reason}). Reconnecting...\n";
    
                    connect_to_websocket ( $url, $service );
                
                });
    
            }, function ($e) {
            
            exit("Could not connect to websocket: {$e->getMessage()}. Exiting...\n");
        
        });
    
    }
    

    This only connects to one resource at a time and second connection goes to waiting, as the first connection closed, second (waiting) connection connects instantly.

    Also, there is unlimited timeout, how to provide or edit timeout? If remote server is not running at the time of creating connection (calling connect_to_websocket () in above code) then the script freezes, it doesn't connect to server when server comes online, which needs force closing/canceling the script

    PHP CLI gives this

    image

    question 
    opened by manjeet-imaniac 7
  • "Ratchet detected invalid OP code when expecting continue frame"

    Using the latest Pawl version (v0.2.1) and I keep getting the following close reasons:

    • Ratchet detected invalid OP code when expecting continue frame
    • Ratchet detected an invalid reserve code

    Both close with close code 1002, I'm not really sure what is happening. Any ideas?

    opened by davidcole1340 7
  • Cannot get TLS to work on proxied websocket with nginx

    Cannot get TLS to work on proxied websocket with nginx

    I can get it to work with a javascript websocket but it will not work with a Pawl websocket. It seems like the handshake always fails and I'm not too sure how to debug it.

    Here's my client code:

    $secureContext = array(
      'verify_peer' => false,
      'verify_peer_name' => true,
      'local_cert' => '/redacted/fullchain.pem',
      'local_pk' => '/redacted/privkey.pem'
    );
    $reactConnector = new \React\Socket\Connector([
        'dns' => '8.8.8.8',
        'timeout' => 10,
        'tls' => $secureContext
    ]);
    $loop = \React\EventLoop\Loop::get();
    $connector = new \Ratchet\Client\Connector($loop, $reactConnector, $secureContext);
    
    $connector('wss://vps1.mazion.tv/wss')->then(function($conn) {
        $conn->send('eyyy!');
        $conn->close();
    }, function ($e) {
        echo "Could not connect: {$e->getMessage()}\n";
    });
    

    Here is my server code:

    class saveTheBeardWS implements MessageComponentInterface {
        protected $clients;
    
        public function __construct() {
            $this->clients = new \SplObjectStorage;
        }
    
        public function onOpen(ConnectionInterface $conn) {
            $this->clients->attach($conn);
        }
    
        public function onMessage(ConnectionInterface $from, $msg) {
            echo $msg;
            foreach ($this->clients as $client) {
                if ($from != $client) {
                    $client->send($msg);
                }
            }
        }
    
        public function onClose(ConnectionInterface $conn) {
            $this->clients->detach($conn);
        }
    
        public function onError(ConnectionInterface $conn, \Exception $e) {
            $conn->close();
        }
    }
    
    $loop = Factory::create();
    
    $server = new Server('127.0.0.1:8843', $loop);
    
    $secureServer = new SecureServer($server, $loop, [
        'local_cert'  => '/redacted/fullchain.pem',
        'local_pk' => '/redacted/privkey.pem',
        'verify_peer' => false,
    ]);
    
    $httpServer = new HttpServer(
        new WsServer(
            new saveTheBeardWS()
        )
    );
    
    $ioServer = new IoServer($httpServer, $secureServer, $loop);
    
    $loop->run();
    

    Here's my nginx configuration with the proxy for the websocket:

    map $http_upgrade $connection_upgrade {                                                                                                                                                                            
        default upgrade;                                                                                                                                                                                               
        '' close;                                                                                            
    }                                 
                                                        
    upstream localhost{                                                                                                                                                                                                
        server 127.0.0.1:8843;                                                                               
    }                                                                                                        
                                                                                                             
    server{                                  
        listen [::]:443 ssl ipv6only=on; # managed by Certbot                                                
        listen 443 ssl; # managed by Certbot                                                                 
        ssl_certificate /redacted/fullchain.pem; # managed by Certbot             
        ssl_certificate_key /redacted/privkey.pem; # managed by Certbot           
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot                                
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot                                  
        server_name redacted;                                                                          
        error_log /redacted/error_log warn;       
        root /redacted;                                                                    
        index index.php;                                                                                                                                                                                               
                                                                                                                                                                                                                       
        #error_page 404 /404.html;                                                                                                                                                                                     
        #error_page 500 502 503 504 /50x.html;                                                                                                                                                                         
                                                                                                                                                                                                                       
        location /wss {                                
            proxy_pass https://localhost;                                                                    
            proxy_ssl_certificate /redacted/fullchain.pem;                                                                                                                                  
            proxy_ssl_certificate_key /redacted/privkey.pem;                      
            proxy_ssl_session_reuse on;                                                                      
            proxy_set_header X-Real-IP $remote_addr;                                                                                                                                                                   
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;                                     
            proxy_http_version 1.1;                                                                          
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;             
            proxy_set_header Host $host;                                                                                                                                                                               
            proxy_set_header X-Forwarded-Proto https;
            proxy_redirect off;                                                                              
            proxy_read_timeout 86400s;             
            proxy_send_timeout 86400s;
            keepalive_timeout 86400s;
            reset_timedout_connection on;
        }
    
        location / {
            try_files $uri $uri/ =404;
        }
    
        location ~ \.php$ {
            include /etc/nginx/conf.d/fastcgi.conf;
            try_files $uri =404;
            fastcgi_index  index.php;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            include fastcgi_params;
        }
    
        location ~ (\.ht|\.json|\.db) {
            deny all;
            return 404;
        }
    
        location ^~ /vendor {
            deny all;
            return 404;
        }
    }
    
    server{
        listen 80;
        listen [::]:80;
        server_name redacted;
        return 301 https://$host$request_uri;
    }
    
    

    If I enable verify_peer on the client-side. It fails to handshake.

    If I understand correctly, with verify_peer disabled I am leaving the door open for MITM attacks. What are the risks associated with keeping verify_peer disabled?

    What am I missing to get the TLS handshake to work?

    opened by TaiTair 0
  • Keep alive support

    Keep alive support

    Added the ability to set up a keep alive interval that will close the connection if it does not receive a reply in time.

    I've modeled the code largely after the one found in the ratchet server, except it's only monitoring the one connection the client is connected to, and the timer is returned, so that it can potentially be canceled later (or be replaced).

    Help with adding tests will be appreciated, as I can't find any test that exchange messages over a real connection - just mock connections or mock connection creation.

    opened by boenrobot 0
  • Implementation to listen for socket.io events

    Implementation to listen for socket.io events

    Do you intend to implement for us to listen for events through socket.io ?

    I need this solution for PHP, because I have a nodejs API running and I communicate some things with socket.io.

    opened by lucasantoniooficial 0
  • send variable

    send variable

    HI,

    I would like to retrieve the variable $argv[1] but I can't.

    <?php
    
    require __DIR__ . '/vendor/autoload.php';
    
    \Ratchet\Client\connect('wss://echo.websocket.org:443')->then(function($conn) {
        $conn->on('message', function($msg) use ($conn) {
            echo "Received: {$msg}\n";
            $conn->close();
        });
    
        $conn->send($argv[1]);
    }, function ($e) {
        echo "Could not connect: {$e->getMessage()}\n";
    });
    
    opened by Romano974 2
  • How to send command line live output to websocket server?

    How to send command line live output to websocket server?

    $app = function (Ratchet\Client\WebSocket $conn) use ($connector, $loop, &$app, $server_id) {
        $conn->on('message', function (\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
            global $server_id;
            $msg = json_decode($msg);
            $proc = popen("ping -t 127.0.0.1",'r');
            if($msg->type=='run') {
                while (!feof($proc))
                {
                    echo $read = fread($proc, 4096);
                    if($read) {
                        $conn->send($read);
                    }
                }
            }
        });
    

    Looks like while (!feof($proc)) blocks main thread... Is there any other way to send live output to websocket server?

    opened by DangerD1024 0
  • Sending binary messages

    Sending binary messages

    I couldn't find a sample in the docs/Readme on how to send binary data. This is one way of doing this:

    $buffer = "\x63\x7c\x77\x7b\xf2\x6b\x6f\xc5\x30\x01";     // just a sample
    $conn->send(new \Ratchet\RFC6455\Messaging\Frame($buffer, true, \Ratchet\RFC6455\Messaging\Frame::OP_BINARY));
    
    opened by atyachin 0
Releases(v0.4.1)
Owner
Ratchet
Asynchronous WebSockets with PHP
Ratchet
Websocket chat room written in PHP based on workerman.

基于workerman的GatewayWorker框架开发的一款高性能支持分布式部署的聊天室系统。

walkor 1.1k Jan 8, 2023
This repository demonstrates exemplary implementation of chat using HTTP and Websocket servers in PHP using Kraken Framework components.

This repository demonstrates exemplary implementation of chat using HTTP and Websocket servers in PHP using Kraken Framework components.

Kraken 48 Aug 11, 2021
Asynchronous iterators and operators.

pipeline Asynchronous iterators and operators. Installation This package can be installed as a Composer dependency. composer require amphp/pipeline Ve

Amp 16 Nov 18, 2022
Complete Pipedrive API client for PHP

Complete Pipedrive API client for PHP Contribute by referral code / link This won't take much time. You could use my referral code or link to get up t

Israel Ortuño 155 Dec 7, 2022
A GETTR.com client library written in PHP with Laravel support.

Gettr API Clinet PHP A GETTR.com client library written in PHP with Laravel support. This library uses unofficial publicly accessible API endpoints of

null 10 Dec 13, 2022
SendCloud client for PHP

SendCloud client for PHP Installation composer require guangda/sendcloud Example $mailData = [ 'to'=>'[email protected]', 'subject'=>'test',

Guangda 3 Aug 27, 2021
Enterprise isEven API Client

zonuexe\isEvenApi This package is a modern, high performance, high modularity and strongly static typed enterprise quality API Client of isEven API fo

USAMI Kenta 3 Aug 26, 2021
Bearer client for the PHP programming language

Bearer PHP Client This is the official PHP client for interacting with Bearer.sh. Installation Install the package by running: composer require bearer

Bearer 9 Oct 31, 2022
An open-source Laravel 8 online store, client area, and billing software specially made for Pterodactyl panel

PteroBilling An open-source Laravel 8 online store, client area, and billing software specially made for Pterodactyl panel           Announcement: An

PteroBilling 18 Nov 12, 2022
The most widely used PHP client for RabbitMQ

php-amqplib This library is a pure PHP implementation of the AMQP 0-9-1 protocol. It's been tested against RabbitMQ. The library was used for the PHP

php-amqplib 4.2k Jan 3, 2023
kafka php client

Kafka-php 中文文档 Kafka-php is a pure PHP kafka client that currently supports greater than 0.8.x version of Kafka, this project v0.2.x and v0.1.x are in

Weibo Ad Platform Open Source 1.4k Jan 5, 2023
Grpc go-server php-client

Grpc go-server php-client

凯 1 Jan 24, 2022
Idiomatic PHP client for Google Compute.

Google Compute for PHP Idiomatic PHP client for Google Compute. API Documentation NOTE: This repository is part of Google Cloud PHP. Any support reque

Google APIs 3 Jun 13, 2022
An unofficial EdgeDB PHP client.

Unofficial EdgeDB HTTP PHP client Requirements PHP >= 8.0 (with fileinfo and mbstring) An EdgeDB server instance (tested with 1.0+9ecadfc) Quickstart

T3d 7 Aug 18, 2022
Smotreshka.tv • Create M3U8 and XMLTV for Kodi : PVR IPTV Simple Client

Smotreshka.tv • Create M3U8 and XMLTV for Kodi : PVR IPTV Simple Client

CDMM 3 Jun 26, 2022
A standalone Amazon S3 (REST) client for PHP 5/CURL

Amazon S3 PHP Class Usage OO method (e,g; $s3->getObject(...)): $s3 = new S3($awsAccessKey, $awsSecretKey); Statically (e,g; S3::getObject(...)): S3::

Donovan Schönknecht 1k Jan 3, 2023
MOFHY Lite is a priceless MyOwnFreeHost Client Area for account management, ticket support system and a free ssl service

MOFHY Lite is a priceless MyOwnFreeHost Client Area for account management, ticket support system and a free ssl service. It has easy to use features much like the WHMCS Digit UI interface.

MOFHY Developers 1 Oct 21, 2022
A PHP implementation of RabbitMQ Client for webman plugin.

workbunny/webman-rabbitmq ?? A PHP implementation of RabbitMQ Client for webman plugin. ?? A PHP implementation of RabbitMQ Client for webman plugin 常

workbunny 15 Dec 15, 2022
PHP DataDog StatsD Client

PHP DataDog StatsD Client This is an extremely simple PHP DogStatsD client. Requires PHP >= 5.6.0. See CHANGELOG.md for changes. For a Laravel-specifi

Datadog, Inc. 175 Nov 28, 2022