swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.42k stars 3.16k forks source link

WebSocket client implementation problem #3204

Closed merlinkory closed 4 years ago

merlinkory commented 4 years ago

i can't find way connect to any WebSocket server. When i tried something like that:

$cli = new swoole_http_client('127.0.0.1', 9502); // or any other WSS

  $cli->on('connect', function ($_cli, $frame) {
            echo "connect";
        });

        $cli->on('close', function ($_cli, $frame) {
            echo "close";
        });

        $cli->on('error', function ($_cli, $frame) {
              echo "error";
        });        

        $cli->on('message', function ($_cli, $frame) {
            var_dump($frame);
        });

application just closing without any messages (errors or warrings)

In docs https://www.swoole.co.uk/docs/modules/swoole-async-http-client i can't find other examples.

Does any way connect to WSS from Swoole?

NHZEX commented 4 years ago

see: https://github.com/swoole/swoole-src/blob/master/examples/ssl/websocket_server.php

merlinkory commented 4 years ago

@NHZEX WebSocket server working - OK! But client implementation with:

$cli->on('message', function ($_cli, $frame) {
            var_dump($frame);
});

not working.

I can read data from WSS only that:

 go(function () {
    $cli = new Co\http\Client("127.0.0.1", 9502);
    $ret = $cli->upgrade("/");
    if ($ret) {
        while(true) {
            $cli->push("hello");
            var_dump($cli->recv());
            co::sleep(0.5);
        }
    }
});

But i can't use "While" for reading data. I want use events when new data coming. Do you have any example?

NHZEX commented 4 years ago
<?php

use Swoole\Coroutine;
use Swoole\Coroutine\Scheduler;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\WebSocket\Frame;

$sch = new Scheduler();
$sch->add(function () {
    $server = new Swoole\Coroutine\Http\Server('127.0.0.1', 9999, false);
    $server->handle('/websocket', function (Request $request, Response $ws) use ($server) {
        $ws->upgrade();
        while (true) {
            /** @var Frame $frame */
            $frame = $ws->recv();
            if ($frame === false) {
                echo "error [{$ws->fd}]: {$server->errMsg}\n";
                break;
            } else if ($frame == '') {
                echo "disconnect [{$ws->fd}]\n";
                break;
            }
            // ...
            echo "server recv data [{$ws->fd}]:{$frame->data}\n";
            $ws->push('server send: hello ' . time());
        }
    });
    $server->start();
});
$sch->add(function () {
    $client = new Swoole\Coroutine\Http\Client('127.0.0.1', 9999);
    $ret = $client->upgrade('/websocket');
    if ($ret) {
        go(function () use ($client) {
            while (true) {
                $message = $client->recv();
                if ($message === false) {
                    echo "error : {$client->errMsg}\n";
                    break;
                } else if ($message == '') {
                    echo "disconnect\n";
                    break;
                }
                // ...
                echo "client recv data: $message\n";
            }
        });
        go(function () use ($client) {
            while (true) {
                $client->push('client send: ' . time());
                Coroutine::sleep(1);
            }
        });
    }
});
$sch->start();
merlinkory commented 4 years ago

yes, it is also work! But i interesting why don't work following code:

$cli = new swoole_http_client('127.0.0.1', 9502); 
        $cli->on('message', function ($_cli, $frame) {
            var_dump($frame);
        });
NHZEX commented 4 years ago

see: https://github.com/swoole/swoole-src/releases/tag/v4.4.8

deprecated: Move async Swoole\Client to ext-async recommended coroutines

latest document (zh): https://wiki.swoole.com/

huanghantao commented 4 years ago

@merlinkory

you need upgrade to the websocket protocol:

<?php

use Swoole\Http\Client;

$cli = new Client('127.0.0.1', 9501);

$cli->on('close', function ($cli) {

});

$cli->on('error', function ($cli) {

});

$cli->on('Message', function ($cli, $frame) {

});

$cli->upgrade('/websocket', function ($cli) {
    for ($i = 0; $i < 100; $i++) {
        $cli->push('hello');
    }
});
matyhtf commented 4 years ago

@merlinkory The third parameter is set to true to enable SSL

$cli = new swoole_http_client('127.0.0.1', 9502, true);