php建立tcp服务请求数据双向通信问题
求问各位大佬,有几个关于tcp
通信的问题指点一下
前提:B/S
网站结构下,现在我在另一台服务器上实现了 ES
搜索,目前是以接口方式提供给原网站,(客户在网页发起搜索,传到 php 服务端
, php 服务端
再发起 curl
请求 ES
接口,获取数据后返回给前端)但是现在需求是一次关键词搜索会搜索十来个业务线(一个业务线对应一个索引),且业务线下还有几个分类。目前我还是用接口,接收数据后,循环搜索 ES
然后返回给 php 服务端
,但是感觉这样的话效率估计会有点慢。
优化策略:目前我想到的是在 ES搜索服务端
用 swoole
扩展建立一个 tcp server
, php 服务端
不再访问接口,而访问该 tcp server
, 也不一次发送所有业务线的搜索及筛选条件,而是循环发送一次发送一条业务线的搜索条件,发送的同时接收 tcp server
的响应,双工通信。
但是我实验了很多次,发现了一些问题:
php 服务端
建立的stream client
建立请求数据后,fclose()
无法关闭该链接,会 __一直链接不返回直到超时__,用 php 的 socket 函数也是这样。(有数据交互才会这样,无数据交互的话建立连接后客户端可以断开)除非服务端发送数据后立马断开链接,但是swoole
文档告诫不要发送后立即断开,但是我也不知道服务端该何时断开链接(什么事件回调(尝试使用onbufferEmpty
事件回调函数,但是压根不会处罚,或其他什么...),但客户端却又无法断开,所以卡住了。php 服务端
如何循环发送的同时接收tcp server
的数据啊,(php 的 stream 函数是阻塞的,这样如何不阻塞来进行双向通信呢)?- 这种架构下,这样的优化策略能实现吗?能有作用吗?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论