首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReactPHP -关闭断开的连接

ReactPHP -关闭断开的连接
EN

Stack Overflow用户
提问于 2016-12-19 18:07:34
回答 1查看 467关注 0票数 1

我使用ReactPHP作为TCP listener组件。此组件侦听传入的连接并与它们交换数据。当客户端与侦听器连接/断开连接时,将更新$connections数组。

代码语言:javascript
复制
$loop = React\EventLoop\Factory::create();
$connections = [];
$socket = new React\Socket\Server($loop);
$socket->on('connection', function ($conn) use($loop, $db){
    global $connections;
    $connections[] = $conn;
    $conn->on('data', function ($data) use ($conn,$loop, $db) {
        global $connections;
        // ...
        // ...
        $conn->on('close', function ($conn) use($loop, $db){
            global $connections;
            if(($key = array_search($conn, $connections, true)) !== FALSE) {
                unset($connections[$key]);
            }   
        });
});
$socket->listen(16555, '127.0.0.1');
$loop->run();

如果客户端是通过远程登录连接的,将发出'close‘,这样我就可以从$connection数组中删除已关闭的连接。但是,连接到我的监听器的某些设备也有问题。如果我关闭设备,'close‘将不会发出。我试着解决周期性计时器的问题:

代码语言:javascript
复制
$loop->addPeriodicTimer(10, function () use($db, $loop){
    global $connections;
    foreach($connections as $c) {
        $remoteAddress = $c->getRemoteAddress();
        $metaData = @stream_get_meta_data($c->stream);
        if(!$metaData) {
            if(($key = array_search($c, $connections, true)) !== FALSE) {
                unset($connections[$key]);
            }   
        }
    }
});

但它似乎还不够可靠。即使客户端断开连接,函数stream_get_meta_data也会返回有效的元数组。

EN

回答 1

Stack Overflow用户

发布于 2020-06-29 19:58:22

这个问题提出已经有一段时间了,但我发现对我有效的方法是使用SplObjectStorage()作为连接池。这是一个(外部)没有索引的集合。对于连接,它工作得非常好。

https://www.php.net/manual/en/class.splobjectstorage.php

我认为你最初的问题的根源是你在foreach中取消了一个元素,它不会自动更新键,并且你可能会把对象的顺序搞乱。

为了在循环中删除一个或多个元素的代码中迭代集合(或数组),使用克隆会更安全。

那么你的池子在哪里:

代码语言:javascript
复制
$connections_pool = new SplObjectStorage();

迭代你会做的事情(根据你的原始请求)

代码语言:javascript
复制
$loop->addPeriodicTimer(10, function () use($db, $loop){
    global $connections_pool;
    foreach(clone($connections_pool) as $c) {
        $remoteAddress = $c->getRemoteAddress();
        $metaData = @stream_get_meta_data($c->stream);
        if(!$metaData) {
            $connections_pool->offsetUnset($c);            
        }
    }
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41220122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档