php建立tcp服务请求数据双向通信问题

发布于 2022-09-07 16:22:02 字数 2943 浏览 21 评论 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();

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文