GatewayWorker icon indicating copy to clipboard operation
GatewayWorker copied to clipboard

关于client_id服务重启后重置

Open wzfjesun opened this issue 5 years ago • 6 comments

你好,每次restart或者reload 服务,client_id都会从00000001 开始重新开始,能否有办法让client_id生成类似uuid的永久不会重复的id呢?即使服务重启也不会重复

wzfjesun avatar Feb 01 '20 09:02 wzfjesun

看了这个issue:https://github.com/walkor/Workerman/issues/286 创建了新类,继承了GatewayWorker\Gateway类,自定义了这个方法gateway::generateConnectionId,但是不知道这个新类该如何使用?请指点一下

wzfjesun avatar Feb 01 '20 09:02 wzfjesun

将gatewayworker/src/Lib/Context.php 里 addressToClientId 和 clientIdToAddress 替换成如下代码。这样就加了一个时间戳前缀,避免重启后client_id冲突

    /**
     * 通讯地址到 client_id 的转换
     *
     * @param int $local_ip
     * @param int $local_port
     * @param int $connection_id
     * @return string
     */
    public static function addressToClientId($local_ip, $local_port, $connection_id)
    {
        return bin2hex(pack('NNnN', time(), $local_ip, $local_port, $connection_id));
    }

    /**
     * client_id 到通讯地址的转换
     *
     * @param string $client_id
     * @return array
     * @throws Exception
     */
    public static function clientIdToAddress($client_id)
    {
        if (strlen($client_id) !== 28) {
            echo new Exception("client_id $client_id is invalid");
            return false;
        }
        return unpack('Ntime/Nlocal_ip/nlocal_port/Nconnection_id', pack('H*', $client_id));
    }

walkor avatar Feb 02 '20 06:02 walkor

测试了可用,非常谢谢~,我在GatewayClient\Gateway里也做了一样处理。不过这样修改源码不方便升级

wzfjesun avatar Feb 03 '20 15:02 wzfjesun

将gatewayworker/src/Lib/Context.php 里 addressToClientId 和 clientIdToAddress 替换成如下代码。这样就加了一个时间戳前缀,避免重启后client_id冲突

    /**
     * 通讯地址到 client_id 的转换
     *
     * @param int $local_ip
     * @param int $local_port
     * @param int $connection_id
     * @return string
     */
    public static function addressToClientId($local_ip, $local_port, $connection_id)
    {
        return bin2hex(pack('NNnN', time(), $local_ip, $local_port, $connection_id));
    }

    /**
     * client_id 到通讯地址的转换
     *
     * @param string $client_id
     * @return array
     * @throws Exception
     */
    public static function clientIdToAddress($client_id)
    {
        if (strlen($client_id) !== 28) {
            echo new Exception("client_id $client_id is invalid");
            return false;
        }
        return unpack('Ntime/Nlocal_ip/nlocal_port/Nconnection_id', pack('H*', $client_id));
    }

替换了之后会出现client_id混乱,onConnect/onMessage/onClose会出现三个不同的client_id 比如 onConnect时,client_id=613f0a567f0000010b5400000001 onMessage时,client_id=613f0a7f7f0000010b5400000001 onClose时,client_id=613f0a997f0000010b5400000001 这是为何?

7iv avatar Sep 13 '21 08:09 7iv

return bin2hex(pack('NNnN', time(), $local_ip, $local_port, $connection_id));

改成

if (!$this->time) {
    $this->time = time();
}
return bin2hex(pack('NNnN', $this->time, $local_ip, $local_port, $connection_id));

试下。

时间戳应该是个定值,只有进程重启了才能变化。

walkor avatar Sep 13 '21 09:09 walkor

return bin2hex(pack('NNnN', time(), $local_ip, $local_port, $connection_id));

改成

if (!$this->time) {
    $this->time = time();
}
return bin2hex(pack('NNnN', $this->time, $local_ip, $local_port, $connection_id));

试下。

时间戳应该是个定值,只有进程重启了才能变化。

非常感谢回复!可以了!

7iv avatar Sep 13 '21 09:09 7iv