0

问题描述

背景 :创建了websocket服务器对象,并且浏览器端可以与这个websocket服务器正常通信,正常监听到各种事件。

业务需要:要实现服务器端主动给目标客户端发送消息。

解决方案:打算把php作为客户端,给服务端发送特定消息,服务端监听到后,推送给相应客户端。

在尝试的过程中,遇到了各种问题,详见如下代码及报错⬇️

//首先创建了websocket服务器对象,监听0.0.0.0:9502端口

    $ws = new \swoole_websocket_server("0.0.0.0", 9502);
    $this->sw = $ws;
    //监听WebSocket连接打开事件
    $ws->on('open', function ($ws, $request) {
        $ws->push($request->fd, "hello, welcome\n");
    });

    $ws->on('connect', function ($ws, $fd){
        echo "Client:Connect. fd {$fd}\n";
    });

    $ws->on('receive', function ($serv, $fd, $reactor_id, $data) {
        echo "Client:Connect. fd : {$fd}\n";
        echo "Client:Connect. data: {$data}\n";
    });

    //监听WebSocket消息事件
    $ws->on('message', function ($ws, $frame) {
        echo "Message: {$frame->data}\n";
        echo "fd: {$frame->fd}\n";
    });

    //监听WebSocket连接关闭事件
    $ws->on('close', function ($ws, $fd) {
        echo "client-{$fd} is closed\n";
    });

    $ws->start();
    
    

之后开始尝试php作为客户端,连接websocket服务,并且发送消息

//php客户端尝试 1
    $host = "127.0.0.1";
    $port = 9502; 
    $client = new \swoole_websocket_server(SWOOLE_SOCK_TCP | SWOOLE_KEEP,SWOOLE_SOCK_SYNC);
    $timeout = 0.5;//超过与服务器交互的超时秒数会自动断开
    $client->connect($host, $port, $timeout);
    $client->send('XXXXXX');
    
    报错:Swoole\Server::__construct(): swoole_server only can be used in PHP CLI mode.
    
//php客户端尝试 2
    $client = new Swoole\Client(SWOOLE_SOCK_TCP | SWOOLE_SYNC);
    if (!$client->connect('127.0.0.1', 9502, 0.5))
    {
        exit("connect failed. Error: {$client->errCode}\n");
    }
    $client->send("hello world\n");
    $client->close();
    
    报错 : 服务端可以监听到 connect事件和close事件,无法监听到send 发送的内容
    
//php客户端尝试 3
    尝试安装官方文档给出的方法:
    apache/php-fpm或其他同步阻塞的PHP程序中可以使用swoole/framework提供的同步WebSocket客户端

    同步WebSocket客户端连接:https://github.com/matyhtf/framework/blob/master/libs/Swoole/Client/WebSocket.php
    代码:
    $service = new WebSocket($host,$port);//service 即为同步WebSocket客户端中的代码
    $send = $service->send('XXXXXX');//调用服务中的send方法
    
    报错:Class 'Swoole\Http\WebSocketParser' not found

期待

   有方法可以实现,php作为客户端,连接已经创建的webscoket服务,并且发送的消息在服务端可以监听到 。 
   
   看到网上看到许多类似的问题,但是都没有很有效的答案。
    
   请问这个问题该如何解决呢 ?  
2019-09-19 提问
1 个回答
1

已采纳

Swoole\Coroutine\Http\Client可以的,请看:https://wiki.swoole.com/wiki/...

另外推荐一下我的YurunHttp,也支持ws客户端:https://github.com/yurunsoft/...

YurunHttp::setDefaultHandler(\Yurun\Util\YurunHttp\Handler\Swoole::class);
go(function(){
    $url = 'ws://127.0.0.1:1234/';
    $http = new HttpRequest;
    $client = $http->websocket($url);
    if(!$client->isConnected())
    {
        throw new \RuntimeException('Connect failed');
    }
    $client->send('data');
    $recv = $client->recv();
    var_dump('recv:', $recv);
    $client->close();
});

上面的是在 Swoole 环境下使用,如果想要在 fpm 中与 WebSocket 服务端通讯,可以去 github 找下 WebSocket Client:https://github.com/search?l=P...

这个问题可以结了~

撰写答案

推广链接