账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    php建立tcp服务请求数据双向通信问题
    46
    0

    求问各位大佬,有几个关于tcp 通信的问题指点一下
    前提:B/S 网站结构下,现在我在另一台服务器上实现了 ES 搜索,目前是以接口方式提供给原网站,(客户在网页发起搜索,传到 php 服务端php 服务端 再发起 curl 请求 ES 接口,获取数据后返回给前端)但是现在需求是一次关键词搜索会搜索十来个业务线(一个业务线对应一个索引),且业务线下还有几个分类。目前我还是用接口,接收数据后,循环搜索 ES 然后返回给 php 服务端,但是感觉这样的话效率估计会有点慢。
    优化策略:目前我想到的是在 ES搜索服务端swoole 扩展建立一个 tcp server, php 服务端 不再访问接口,而访问该 tcp server, 也不一次发送所有业务线的搜索及筛选条件,而是循环发送一次发送一条业务线的搜索条件,发送的同时接收 tcp server 的响应,双工通信。
    但是我实验了很多次,发现了一些问题:

    1. php 服务端 建立的 stream client 建立请求数据后,fclose() 无法关闭该链接,会 __一直链接不返回直到超时__,用 php 的 socket 函数也是这样。(有数据交互才会这样,无数据交互的话建立连接后客户端可以断开)除非服务端发送数据后立马断开链接,但是 swoole 文档告诫不要发送后立即断开,但是我也不知道服务端该何时断开链接(什么事件回调(尝试使用 onbufferEmpty 事件回调函数,但是压根不会处罚,或其他什么...),但客户端却又无法断开,所以卡住了。
    2. php 服务端 如何循环发送的同时接收 tcp server 的数据啊,(php 的 stream 函数是阻塞的,这样如何不阻塞来进行双向通信呢)?
    3. 这种架构下,这样的优化策略能实现吗?能有作用吗?
      php 服务端请求 ES tcp server 部分代码
    $streamClient = stream_socket_client("tcp://{$tcpHost}:{$tcpPort}", $errno, $errstr);
    // 该数组是所有业务线的分类结构,及每条业务线要搜索的关键字,单个元素对应一条业务线
    $categoriesFilter = [];
    foreach ($categoriesFilter as $categoryFilter) {
            fwrite($streamClient, json_encode($categoryFilter);
    }

    然后我就不知道该如何实现写的同时接收数据了。并保证每条业务线的数据都发送了,也收到响应了。
    ES tcp server 部分代码

    $searchServer = new \swoole_server('0.0.0.0', 9501);
    $searchServer->on('connect', function (\Swoole\Server $server, $fd) {
                dump($server->connection_info($fd));
            });
    $searchServer->on('receive', function (\Swoole\Server $server, $fd, $reactor_id, $request) {
        global $keyword;
        global $elastic;
        $requestArray = json_decode($request, true);
        $keyword = $requestArray;
        // es 搜索代码
        $result = $elastic->indexFilterAndSearch($requestArray);
        $server->send($fd, json_encode($result));
    });
    $searchServer->on('WorkerStart', function (\Swoole\Server $server, $work_id) {
        global $elastic;
        $elastic = new ElasticSearch;
    });
    $searchServer->on('close', function (\Swoole\Server $server, $fd, $reactorId) {
        global $keyword;
        $clientConnectionInfo = $server->connection_info($fd);
        file_put_contents('swoole_log.log', json_encode([
            'connectionTime' => date('Y-m-d H:i:s', $clientConnectionInfo['connect_time']),
            'closeTime' => date('Y-m-d H:i:s'),
            'keyword' => $keyword,
            'ip' => $clientConnectionInfo['remote_ip']
        ]) . PHP_EOL, FILE_APPEND);
    });
    // 该回调事件从未执行
    $searchServer->on('bufferEmpty', function (\Swoole\Server $server, $fd) {
         dump("send this $fd message is down");
    });
    $searchServer->start();

    求各位大佬指点一下,这样优化行不行?如果行的话,我上面的两个问题该从那方面,那里入手解决啊。。。

    1
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 冷玉 普通会员 1楼
      502 Bad Gateway

      502 Bad Gateway


      nginx
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部