Giter Club home page Giter Club logo

pawl's Introduction

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:

<?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('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:

<?php

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

pawl's People

Contributors

andreybolonin avatar cboden avatar claudiosdc avatar clue avatar davidwdan avatar ekstazi avatar hhxsv5 avatar hugohenrique avatar mbabker avatar mbonneau avatar nazar-pc avatar nek- avatar nhedger avatar sadortun avatar simonfrings avatar valga avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pawl's Issues

status code :407

HTTP/1.1 407 Proxy Authentication Required
Content-Length: 33?

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.

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 :(

`close` emitted with React\Stream\Stream

I've had some errors in my application where close is emitted with an instance of React\Stream\Stream, which causes my application to crash when I try to print the close code and reason.

It is because of this, possibly change it so stream closes emit with [0, 'PHP stream closed']?

Auto Reconnect

  • Optional auto-reconnect component
  • Queue send() messages when not connected

How to reopen a closed connection?

Hello,
I'm using your lib to do some test on an api and i would like to know how to reopen a connection closed using your exemple on the event close

<?php

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

    $loop = React\EventLoop\Factory::create();
    $connector = new Ratchet\Client\Connector($loop);

    $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();
    });

    $loop->run();

How to reopen a connection after this line echo "Connection closed ({$code} - {$reason})\n";

Regards

Unable to complete SSL/TLS handshake

Hello, i'm having an issue with a specific wss server. Curiously enough "wss://echo.websocket.org" works just fine. The endpoint i'm trying is "wss://connect-bot.classic.blizzard.com/v1/rpc/chat" This is a known good endpoint, works fine in javascript and other services.

<?php

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

    \Ratchet\Client\connect('wss://connect-bot.classic.blizzard.com/v1/rpc/chat')->then(function($conn) {
        $conn->on('message', function($msg) use ($conn) {
            echo "Received: {$msg}\n";
            $conn->close();
        });

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

composer::

me@server [~/public]# cat composer.json
{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.6.4",
        "laravel/framework": "5.4.*",
        "laravel/tinker": "~1.0",
        "ratchet/pawl": "^0.2.3"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.7"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "optimize-autoloader": true
    }
}
me@server [~/public]# composer show -i
You are using the deprecated option "installed". Only installed packages are shown by default now. The --all option can be used to show all packages.
dnoegel/php-xdg-base-dir              0.1     implementation of xdg base di...
doctrine/inflector                    v1.1.0  Common String Manipulations w...
doctrine/instantiator                 1.0.5   A small, lightweight utility ...
erusev/parsedown                      1.6.2   Parser for Markdown.
evenement/evenement                   v2.0.0  Événement is a very simple ...
fzaninotto/faker                      v1.6.0  Faker is a PHP library that g...
guzzlehttp/psr7                       1.4.2   PSR-7 message implementation ...
hamcrest/hamcrest-php                 v1.2.2  This is the PHP port of Hamcr...
jakub-onderka/php-console-color       0.1
jakub-onderka/php-console-highlighter v0.3.2
laravel/framework                     v5.4.23 The Laravel Framework.
laravel/tinker                        v1.0.0  Powerful REPL for the Laravel...
league/flysystem                      1.0.40  Filesystem abstraction: Many ...
mockery/mockery                       0.9.9   Mockery is a simple yet flexi...
monolog/monolog                       1.22.1  Sends your logs to files, soc...
mtdowling/cron-expression             v1.2.0  CRON for PHP: Calculate the n...
myclabs/deep-copy                     1.6.1   Create deep copies (clones) o...
nesbot/carbon                         1.22.1  A simple API extension for Da...
nikic/php-parser                      v3.0.5  A PHP parser written in PHP
paragonie/random_compat               v2.0.10 PHP 5.x polyfill for random_b...
phpdocumentor/reflection-common       1.0     Common reflection classes use...
phpdocumentor/reflection-docblock     3.1.1   With this component, a librar...
phpdocumentor/type-resolver           0.2.1
phpspec/prophecy                      v1.7.0  Highly opinionated mocking fr...
phpunit/php-code-coverage             4.0.8   Library that provides collect...
phpunit/php-file-iterator             1.4.2   FilterIterator implementation...
phpunit/php-text-template             1.2.1   Simple template engine.
phpunit/php-timer                     1.0.9   Utility class for timing
phpunit/php-token-stream              1.4.11  Wrapper around PHP's tokenize...
phpunit/phpunit                       5.7.20  The PHP Unit Testing framework.
phpunit/phpunit-mock-objects          3.4.3   Mock Object library for PHPUnit
psr/http-message                      1.0.1   Common interface for HTTP mes...
psr/log                               1.0.2   Common interface for logging ...
psy/psysh                             v0.8.5  An interactive shell for mode...
ramsey/uuid                           3.6.1   Formerly rhumsaa/uuid. A PHP ...
ratchet/pawl                          v0.2.3  Asynchronous WebSocket client
ratchet/rfc6455                       v0.2.2  RFC6455 WebSocket protocol ha...
react/cache                           v0.4.1  Async caching.
react/dns                             v0.4.9  Async DNS resolver for ReactPHP
react/event-loop                      v0.4.3  Event loop abstraction layer ...
react/promise                         v2.5.1  A lightweight implementation ...
react/promise-timer                   v1.1.1  Trivial timeout implementatio...
react/socket                          v0.8.0  Async, streaming plaintext TC...
react/socket-client                   v0.5.3  Async connector to open TCP/I...
react/stream                          v0.4.6  Basic readable and writable s...
sebastian/code-unit-reverse-lookup    1.0.1   Looks up which function or me...
sebastian/comparator                  1.2.4   Provides the functionality to...
sebastian/diff                        1.4.3   Diff implementation
sebastian/environment                 2.0.0   Provides functionality to han...
sebastian/exporter                    2.0.0   Provides the functionality to...
sebastian/global-state                1.1.1   Snapshotting of global state
sebastian/object-enumerator           2.0.1   Traverses array structures an...
sebastian/recursion-context           2.0.0   Provides functionality to rec...
sebastian/resource-operations         1.0.0   Provides a list of PHP built-...
sebastian/version                     2.0.1   Library that helps with manag...
swiftmailer/swiftmailer               v5.4.8  Swiftmailer, free feature-ric...
symfony/console                       v3.2.8  Symfony Console Component
symfony/css-selector                  v3.2.8  Symfony CssSelector Component
symfony/debug                         v3.2.8  Symfony Debug Component
symfony/event-dispatcher              v3.2.8  Symfony EventDispatcher Compo...
symfony/finder                        v3.2.8  Symfony Finder Component
symfony/http-foundation               v3.2.8  Symfony HttpFoundation Component
symfony/http-kernel                   v3.2.8  Symfony HttpKernel Component
symfony/polyfill-mbstring             v1.3.0  Symfony polyfill for the Mbst...
symfony/process                       v3.2.8  Symfony Process Component
symfony/routing                       v3.2.8  Symfony Routing Component
symfony/translation                   v3.2.8  Symfony Translation Component
symfony/var-dumper                    v3.2.8  Symfony mechanism for explori...
symfony/yaml                          v3.2.8  Symfony Yaml Component
tijsverkoyen/css-to-inline-styles     2.2.0   CssToInlineStyles is a class ...
vlucas/phpdotenv                      v2.4.0  Loads environment variables f...
webmozart/assert                      1.2.0   Assertions to validate method...

php version:

me@server [~/public]# php -v
PHP 7.1.5 (cli) (built: May 11 2017 12:28:19) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

php modules:

me@server [~/public]# php -m
[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gd
gettext
gmp
hash
http
iconv
imap
intl
json
libxml
mbstring
mcrypt
mysqli
OAuth
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
pgsql
Phar
posix
propro
raphf
readline
Reflection
session
shmop
SimpleXML
soap
sockets
SPL
sqlite3
standard
tidy
tokenizer
xml
xmlreader
xmlrpc
xmlwriter
xsl
zip
zlib

[Zend Modules]

OS stuff:

me@server [~/public]# uname -a
Linux a2ss43.a2hosting.com 2.6.32-673.26.1.lve1.4.27.el6.x86_64 #1 SMP Sun May 7 19:22:54 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
me@server [~/public]# openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013

When I connect to server this is the output:

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

Timeout for connection to server

Hello. I want to do this: If server does not respond for 2 seconds - cancel connection and return message with error to client. How to do this by this library?

Btw thanks for nice work!

Connection timeout

when i send this string PHP client stopped by timeout

{"event":"newMessage","data":{"toUserIds":["105","98"],"message":{"dialogId":"37","userId":"105","text":"1756","createDt":"2016-08-10 07:44:11","status":1,"id":"184","updateDt":"2016-08-10 07:44:11"}}}

but, if i remove any element from data, like this (i removed last element updateDt)

{"event":"newMessage","data":{"toUserIds":["105","98"],"message":{"dialogId":"37","userId":"105","text":"1756","createDt":"2016-08-10 07:44:11","status":1,"id":"184"}}}

all works.
why?

My php client:

RatchetClient\connect("ws://{$this->host}:{$this->port}")
            ->then(
                function(WebSocket $conn) use ($event, $data) {
                    $conn->on('message', function($msg) use ($conn) {
                        $conn->close();
                    });
                    $conn->send(json_encode(['event' => $event, 'data' => $data]));
                },
                function ($e) {
                    throw new RuntimeException("Could not connect: {$e->getMessage()}\n");
                }
            );

My server - https://github.com/t4web/Websocket/blob/master/src/Server.php

When i send first string in console i see:

# php public/index.php websocket start
server started on port 8165
**Debug: New client connected

thats all.

When i send second string (without one element in data), i see:

# php public/index.php websocket start
server started on port 8165
**Debug: New client connected
**Debug: Income message: array (
  'event' => 'newMessage',
  'data' => 
  array (
    'toUserIds' => 
    array (
      0 => '105',
      1 => '98',
    ),
    'message' => 
    array (
      'dialogId' => '37',
      'userId' => '105',
      'text' => '1756',
      'createDt' => '2016-08-10 07:44:11',
      'status' => 1,
      'id' => '184',
    ),
  ),
)
**Debug: Client close connection

TCP connection

hello . The Pawl support persistent TCP ? but I cannot seek out this code ?

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

wss not work

"PHP message: PHP Catchable fatal error: Argument 1 passed to Devristo\Phpws\Client\WebSocket::Devristo\Phpws\Client{closure}() must be an instance of React\Stream\Stream, instance of React\SocketClient\SecureStream given, called in /var/www//vendor/react/promise/src/FulfilledPromise.php on line 24 and defined in /var/www//vendor/devristo/phpws/src/Devristo/Phpws/Client/WebSocket.php on line 95" while reading response header from upstream, client: , server: *, request: "GET /api.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: ""

@cboden

How to personnalize the loop

Hello,
I'm trying to use your lib for an api
i would like to personnalize the loop and let the connection open for my script and send different api call.

How can i personnalize this code to add my function in the loop?
I can connect but i can't do what i want.
Here the basic code with my connection


<?php


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

$loop = React\EventLoop\Factory::create();
$connector = new Ratchet\Client\Connector($loop);
print("Initialisation des variable");

$connector('wss://ws.binaryws.com/websockets/v3')
        ->then(function(Ratchet\Client\WebSocket $conn) {
            $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
                print "Received: {$msg}\n";
                $conn->close();
            });

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

            $conn->send('{"authorize": "myapikey"}');
        }, function(\Exception $e) use ($loop) {
            print "Could not connect: {$e->getMessage()}\n";
            $loop->stop();
        });

$loop->run();

Have you an example?
Regards,

Segmentation Fault

I want to connect to a websocket using PHP, but a segmentation fault is thrown.

Code:

\Ratchet\Client\connect('wss://be.huobi.com/ws');

Result:

Segmentation Fault(Core Dumped)

Environment:

  1. Libevent 2.1.8
  2. PHP 7.1

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.

Add a way to decode binary frames

At the moment there is no way to decode binary frames (opcode 2) which is why I had to import the code into my project. Perhaps there should be a way to decode the binary frames?

I am using this code:

if ($this->_message->getOpcode() == Frame::OP_BINARY) {
    $message = zlib_decode($message);
}

however, this won't work with all encodings.

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

Error: Class not found

Hi. I tried to use Pawl but there was a problem in Ratchet\Client\Factory and Ratchet\Client\WebSocket. I can't find any mention about these classes.
My composer config is
"require": {
"cboden/ratchet": "0.3.",
"react/socket-client": "0.4.
"
}
What's the trick? Where can I get required classes?

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

"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?

Error with PHP 5.6

I updated my version of php to 5.6 and now I'm getting this error message:

Could not connect: Unable to complete SSL/TLS handshake: stream_socket_enable_crypto(): Peer certificate CN=*.domain.com' did not match expected CN=`00.000.87.163'``

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!

Tag a Release

@cboden Would it be possible to tag a release? I'm trying to streamline the installation of Thruway and right now, installing Pawl is an extra step.

Is `onOpen` possible?

I'm trying to look through the source to see if there's a way to have an on handler for "open" but all I'm seeing are close and message. Is there a way I'm missing to be able to fire an event on the opening of the connection and before the first message comes in?

connection problem to local addresses

I can't connect to any address which is resolved by hosts file. It is related to react dns resolver which ignores hosts file and when I run server with ratchet websockets app class I can't connect to server with IP because route is not matched. is there any way to solve this?

Keep socket connection open , and send push messages from other classes

I have made a helper class like :

class SocketPush
{
    /**
     * Helper Function to broad a message.
     * The metadata required to send message should be part of message itself
     * Example usage:
     * SocketPush::SendBroadcast(SocketPush::constructMessage(PusherServer::$PUSHABLE_USER_PREFIX . '1'
     * , PusherServer::$ACTION_PUSH, "coming your way"));
     * @param $msg string
     */
    public static function SendBroadcast($msg)
    {
        $loop = Factory::create();
        $connector = new Connector($loop);
        $connector('ws://127.0.0.1:8080', [], ['Origin' => 'origin'])
            ->then(function (WebSocket $conn) use ($msg, $loop) {
                $conn->remoteAddress = '127.0.0.1';
                $conn->on('close', function ($code = null, $reason = null) {
                });
                $conn->send($msg);
                $conn->close();
            }, function (\Exception $e) use ($loop) {
                echo $e->getMessage();
                $loop->stop();
            });
        $loop->run();
    }
}

I am using push notification using ratchet, and so , whenever I need the server to send a message to a client, I call the sendBroadcast method of this client.
What this does is, everytime a message needs to be sent, it initiates a connection , then sends the message, then closes it(this sounds like unnecessary overhead)

Is is possible to keep the connection open at all times (if for some reach it disconnects, reconnect), and , call the same send broadcast method from other classes to send message ?

Use React HttpClient

Replace SocketClient with HttpClient. HttpClient needs to support 101 header first.

Getting "Connection closed before handshake"

Hi there, I'm having trouble connecting to the following ws "wss://streamer.cryptocompare.com"

docs here, https://www.cryptocompare.com/api/#-api-web-socket-

my implementation is the following

Btw, I'm running it on a laravel command "handle()' method

\Ratchet\Client\connect('wss://streamer.cryptocompare.com')->then(function($conn) {
	$conn->on('m', function($msg) use ($conn) {
		echo "Received: {$msg}\n";
		$conn->close();
	});


	$conn->send(['SubAdd' => '5~CCCAGG~BTC~USD']);
}, function ($e) {
	echo "Could not connect: {$e->getMessage()}\n";
});

basically the same first example from the docs, now, I've already got another working ws client in another project, however, in that other project I had to toy around with the headers, but this time, I haven't been able to make it work, also, I managed to implement this exact endpoint in nodejs using socket.io as a proof of concept, and it worked perfectly!, but really need to make it work on php

any idea, where it could be breaking, or where exactly to look at?

Connector promise won't execute any of the callbacks

I'm running this client from an MVC web application that runs in Apache, so I just want to do a open-send-close operation. I don't want to keep connection persisted or anything. Basic stuff.

Here's my code (this is a Class, not a script. I'm just pasting what's important:

// imports
use React\EventLoop\Factory;
use Ratchet\Client\Connector;

// Constructor
$this->loop = Factory::create();
$this->connector = new Connector($this->loop);

// Connection
$uri = "ws://127.0.0.1:3080/app";     // NO SERVER IS LISTENING HERE, SO IT SHOULD CRASH, I BELIEVE

error_log("connecting to {$uri}");     // THIS LINE GETS CALLED PERFECTLY

$this->connector->__invoke($uri)   // THIS METHOD IS GETTING CALLED PERFECTLY
    ->then(
        function ($conn) {
            die();                                  // THERE IS A DIE() HERE BUT NEVER GETS CALLED
            error_log("connected");

            $conn->on('message', function ($msg) {
                error_log("message received");

                 $conn->close();
            });
        },
        function (Exception $e) {
            die();                                   // THERE IS ANOTHER DIE() HERE BUT NEVER GETS CALLED
            error_log("errored");
        }
    );

As you can see, there is a die() call in both callback, but it's never called. It should be dying. What am I doing wrong?

UPDATE: I did try with an URI that has an actual server listening to it, but didn't work either, so I'm trying to rule out the problem resides in the ip/hosts since i'm connecting from localhost using hostnames.

Pass custom dns resolver

It will be great, if I can pass custom dns resolver to \Ratchet\Client\connect (and pass it to \Ratchet\Client\Connector construct).

Option to disable SSL certificate verification

I'm trying to connect to a websocket server and am getting this error:

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

I should have a valid SSL certificate(it works ok in the browser) however I'm running a non-standard websocket server application which may have issues with the full chain.
I'm trying to disable SSL certificate verification for testing but I'm not seeing an obvious way to do that.

Sending Messages to Ratchet server with Pawl

I am running a websocket server with Ratchet. The problem is when I have the server execute shell scripts based on incoming messages, I need there to be a way to let the server know that the script is finished executing. My solution was for the shell scripts to call a php script that sets up a client using pawl, and then sends a message to the server informing it of the completed task. Whenever I do this, the server hangs, and needs to be restarted. When I call php script directly from the command line, a socket is created, and a message is sent, but when the server calls the same script with "exec" or through executing a sh script which then calls the php script, the server hangs, produces no errors, and needs a restart. I imagine it has something to do with the client trying to connect to itself because when I use an invalid ip, it produces an error, but when I use the actual ip, it hangs. Please help.

Error conexion SSL

Example:

<?php

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

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

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

?>

Result: Could not connect: Unable to complete SSL/TLS handshake:

Wamp2 error

I am pretty new to websockets and I tried making a websocket connection with poloniex. This is what I have run:

$loop = Factory::create();
        $connector = new Connector($loop);

        $connector('wss://api.poloniex.com')
            ->then(function(WebSocket $conn) {
                $conn->send('{"event": "subscribe","channel":"ticker","pair": "BTC_ETH"}');

                $conn->on('message', function(MessageInterface $msg) use ($conn) {
                    var_dump($msg);
                });
            }, function(\Exception $e) use ($loop) {
                /** hard error */
                echo "Could not connect: {$e->getMessage()}\n";
                $loop->stop();
            });

        $loop->run();

But I received error:

Could not connect: HTTP/1.1 400 This server only speaks WebSocket subprotocols wamp.2.cbor.batched, wamp.2.cbor, wamp.2.msgpack.batched, wamp.2.msgpack, wamp.2.json.batched, wamp.2.json

I also tried $connector('wss://api.poloniex.com', ['wamp']) and $connector('wss://api.poloniex.com', ['wamp2']) but same error persists

How to use with push server with Ratchet?

Hi,
I developed on local a site with Ratchet and your push server using ZeroMQ.
All works fine untill today when I wrote to web provider to install ZeroMQ on a VPS to bring site from local to production server.
They told me zeromq not supported by cPanel and Easy Apache 3 or 4.
So I'm in panic!
Please can you update Ratchet Push Server Sample for using with Pawl?

Thanks in advance

Add ping event

I see there is a pong event in the handleData function. That doesn't seem very useful for a client library. From my understanding of the spec, only the server sends a ping event, so in theory, under normal circumstances, the 'pong' event will never be triggered. I think having a ping event would be more useful. I have added a ping emitter as shown below. Seems to be working just fine. Can this be added?

case Frame::OP_PING:
    $this->send(new Frame($frame->getPayload(), true, Frame::OP_PONG));
    $this->emit('ping', [$frame, $this]);
    break;

HHVM Warning: unable to shutdown socket

When running with hhvm I get:

Warning: unable to shutdown socket [107]: Transport endpoint is not connected in /root/phpstuff/Pawl/src/WebSocket.php on line 108

Any way to check if connection is open?

I've been having issues where I am getting Tried to write to closed stream. after connecting so I'm planning to implement a message queue, however I have no way to check if the stream is writable as it is protected. Any way I could check or could I send in a PR for it?

Unable to complete SSL/TLS handshake

Hello. I'm trying to avoid SSL error, but who understands why it does not work?

Error:

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

Code Part:

$url_twoway_list = "wss://public.bitpoint.co.jp/bpj-api/twoWay?access_token=" . $access_token;
$loop = React\EventLoop\Factory::create();
$connector = new Ratchet\Client\Connector($loop);
$connector($url_twoway_list,['tls'],['verify_peer' => false,'verify_peer_name' => false])->then(function(Ratchet\Client\WebSocket $conn) {

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.