回调函数中的 reactor_id 和 fd

服务器的onConnectonReceiveonClose回调函数中会携带reactor_idfd两个参数。

  • $reactor_id是来自于哪个reactor线程
  • $fdTCP客户端连接的标识符,在Server实例中是唯一的,在多个进程内不会重复
  • fd 是一个自增数字,范围是1 ~ 1600万,fd超过1600万后会自动从1开始进行复用
  • $fd是复用的,当连接关闭后fd会被新进入的连接复用
  • 正在维持的TCP连接fd不会被复用

调用Server->send/Server->close函数需要传入$fd参数才能被正确的处理。如果业务中需要发送广播,需要用apcredisMySQLmemcacheSwoole\Tablefd的值保存起来。

function my_onReceive($serv, $fd, $reactor_id, $data)  {
    //向Connection发送数据
    $serv->send($fd, 'Swoole: '.$data);

    //关闭Connection
    $serv->close($fd);
}

fd 为什么使用整型

$fd使用整型而不是使用对象,主要原因是Swoole是多进程的模型,在Worker进程/Task进程中随时可能要访问某一个客户端连接,如果使用对象,那就需要进行Serialize/Unserialize。增加了额外的性能开销。$fd 如果是整数那就可以直接存储传输被使用。

PHP层可以自行将客户端连接封装成对象。面向对象的好处是可读性更好,对连接的操作可以封装到方法中。如

$connection->send($data);
$connection->close();


  • 吾爱

    封装成对象也仅在当前进程中,同一个连接在断线前一直绑定在一个worker上? 否则不知道封装有啥意义,又不是共享内存

  • 落落

    fd 到底是什么的缩写? 找来找去也找不到,不知道原称是什么,感觉很难受

  • twosee

    file descriptor

  • 头上有灰机

    弱弱的问一句,确定唯一客户端,只需要 fd 就行了吗?还是同时需要 reactor_id 和 fd 才能确定唯一客户端?

  • Rango

    fd 是全局唯一的。

  • 飞书非书

    能拿到fd 对应的 客户端ip吗?