我有一个laravel应用程序,在其中我使用php棘轮库在客户端和用户之间进行实时通信的持久连接(现在它只是一种方式,即,只有服务器可以发送消息到客户端)。
通过这种架构,我怎样才能拥有多个这些laravel服务器,每个服务器都有自己的客户端连接,以进行相互通信?
我正在考虑使用REDIS,并拥有一台redis服务器,我的所有节点都将连接到该服务器(使用pub sub)。
我的服务类似于群发消息应用程序(一个用户有很多群组,一个群组有很多用户),到目前为止(现在我只有一台服务器而没有redis),我得到了所有用户的群组,并订阅他们的主题(主题名称类似GROUP_ 1,GROUP_ 8,GROUP_ 99等)。
我想知道每个节点如何在redis中订阅特定主题(将所有redis消息发送到我的所有节点都没有意义。)
Laravel的例子说使用像这样的php artisan命令:
class RedisSubscribe extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'redis:subscribe';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Subscribe to a Redis channel';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
Redis::subscribe(['test-channel'], function($message) {
echo $message;
});
}
}
但是,我希望能够在运行时(在运行artisan命令之后)订阅,取消订阅某些主题。我怎么能在laravel中做到这一点?
答案 0 :(得分:3)
因此,如果我完全理解您的问题,那么您正在寻找一种向多个WebsocketServers上连接的用户发送消息的方法。
您希望通过将其发送到没有订阅接收主题/频道的客户的websocket服务器来获得开销。
第1部分回答:
我目前也在大约50个不同的websocketServers上做这个,所以这是一个功能设计。 我将所有50个websocket服务器的IP地址存储在我的数据库中。 我还为每个websocket服务器附加了8096个用户的限制。
发布/订阅
对于想要连接的每个用户,我首先调用API来确定用户必须连接到哪个websocket。这是为了使一个服务器没有8k用户而其他服务器为空。另一种实现此目的的方法是使用负载均衡并连接负载均衡器后面的所有不同的websocket服务器。
完成此操作后,我总是保存用户在我的数据库中连接的websocketserver。如果用户还订阅了频道,则会在数据库中添加新条目。
当用户取消订阅某个主题/频道时,该频道的用户条目将从数据库中删除。
发送消息
要向我正在使用API的不同用户发送消息,因为我只使用从服务器到客户端的websocket,而不是相反。
在用户向其他人发送消息时,API调用也会注意到我运行的推送服务器。推送服务器也被连接到数据库。
对于推送服务器接收到的每条消息,它会在那个时刻获得哪些用户订阅该频道/主题。
然后它只会将数据发送到具有订阅此频道/主题的连接/用户的websockets。
第2部分回答
在上一个答案中已经有点了,但重点是只将数据发送到具有侦听客户端的websockets。这些信息来自数据库。
数据库就像我目前针对这个问题的方案一样(只包括它的重要部分。
模板: table(column1,column2);
如果您需要更多信息,请告诉我们。