hyperf:服务端通过makeSocket主动给特定用户推送长连接消息注意事项

公司网站端有这么一个场景:用户扫码(微信扫码或支付宝扫码)充值成功后,在微信或支付宝付款结果通知到服务端后,服务端要通过socket长连接再通知给充值用户提示充值成功。

公司测试环境部署的hyperf服务分别只有一台,但是线上生产环境部署的hyperf服务有两台,这两台基于同一个redis服务维护的socket长连接信息。

但在使用过程中发现,在测试环境前端能收到服务端推送的emit事件消息,但在线上环境,有时收不到,有时能收到。

代码如下:

$container = ApplicationContext::getContainer();
$socket = $container->get(\App\Kernel\SocketIO::class)->makeSocket((int)$user['fd']);
$socket->emit('pc_pay_notice', json_encode($data));

上面的代码改为:

$io = ApplicationContext::getContainer()->get(\App\Kernel\SocketIO::class);
$io->of('/')->to($user['sid'])->emit('pc_pay_notice', json_encode($data));

后线上环境用户100%能收到。

分析原因如下:单机的情况下,socket长连接,一个fd对应一个sid,但是在两台socket服务的情况下,通过hyperf的makeSocket方式创建的socket连接,只有50%的可能能通知到用户。

而基于用户本身长连接中的sid值信息,如“60800f6b3e3f0#166”,则100%能推送成功,因为hyperf基于同一个redis服务维护的长连接已经保证了多机的情况下,同一时刻同一用户的sid值只有一个。

但是通过makeSocket方式创建的socket连接,如果当时创建连接的服务所在的服务器恰巧与用户当前所用的长连接所在的服务器是同一台,则用户也能收到消息,但是如果不在同一台,用户就收不到服务端主动推送的emit消息了。

你可能感兴趣的:(hyperf,hyperf,socket,makeSocket,websocket,php)