Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php、laravel、socket-水平缩放技术_Php_Sockets_Laravel_Redis_Ratchet - Fatal编程技术网

Php、laravel、socket-水平缩放技术

Php、laravel、socket-水平缩放技术,php,sockets,laravel,redis,ratchet,Php,Sockets,Laravel,Redis,Ratchet,我有一个laravel应用程序,在其中我使用php ratchet库在客户端和用户之间建立持久连接,以便进行实时通信(目前这只是一种方式,即只有服务器可以向客户端发送消息) 有了这种架构,我如何让多个这样的laravel服务器相互通信,每个服务器都有自己的一组客户端连接到它们 我正在考虑使用REDIS,并拥有一个REDIS服务器,我的所有节点都将连接到该服务器(使用pub-sub) 我的服务类似于一个群组消息应用程序(一个用户有多个群组,一个群组有多个用户),到目前为止(现在我只有一台服务器,没

我有一个laravel应用程序,在其中我使用php ratchet库在客户端和用户之间建立持久连接,以便进行实时通信(目前这只是一种方式,即只有服务器可以向客户端发送消息)

有了这种架构,我如何让多个这样的laravel服务器相互通信,每个服务器都有自己的一组客户端连接到它们

我正在考虑使用REDIS,并拥有一个REDIS服务器,我的所有节点都将连接到该服务器(使用pub-sub)

我的服务类似于一个群组消息应用程序(一个用户有多个群组,一个群组有多个用户),到目前为止(现在我只有一台服务器,没有redis),我获得了所有用户的群组,并为他订阅这些主题(主题名称类似于群组1、群组8、群组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命令之后)订阅、取消订阅某些主题。我怎么能在拉威尔做到这一点

  • 因此,如果我完全理解您的问题,那么您正在寻找一种向连接在多个WebSocketServer上的用户发送消息的方法

  • 通过将其发送到没有订阅接收主题/频道的客户端的websocketservers,您不需要任何开销


  • 第一部分答案:

    我目前也在大约50个不同的WebSocketServer上这样做,所以这是一个功能设计。 我的数据库中存储了所有50个WebSocketServer的IP地址。 我还对每个WebSocketServer附加了8096个用户的限制

    发布/订阅部分

    对于每个想要连接的用户,我首先调用API来确定用户必须连接到哪个websocket。这是为了一台服务器没有8k用户,而其他服务器是空的。实现这一点的另一种方法是使用负载平衡,并在负载平衡器后面连接所有不同的WebSocketServer

    完成后,我总是在数据库中保存用户连接到的websocketserver。如果用户也订阅了频道,则会在数据库中添加一个新条目

    当用户取消订阅某个主题/频道时,该频道的用户条目将从数据库中删除

    发送消息

    为了向不同的用户发送消息,我目前也在使用API,因为我只使用从服务器到客户端的websocket,而不是相反的方式

    当用户向其他人发送消息时,API调用也会注意到我正在运行的pushserver。pushserver也连接到数据库

    对于pushserver接收到的每一条消息,它都会及时获取订阅该频道/主题的用户

    然后,它将只将数据发送到具有订阅了您正在寻址的频道/主题的连接/用户的WebSocket


    第二部分答案

    这在前面的答案中已经有点类似了,但其要点是只向具有侦听客户端的WebSocket发送数据。这些信息是从数据库中获取的

    我目前针对这个问题的类似数据库的方案(只包括其中的重要部分)

    模板: 表(第1栏、第2栏)

    • 用户(userId)
    • Websocket(websocketId、IP地址、用户限制)
    • 连接(connectionId、user.userId、websocket.websocketId)
    • 订阅(connection.connectionId、channelId)

    如果您需要更多信息,请告诉我。

    1.每个主题都是不同的频道有意义吗?如果有,这就是您的答案。2.在运行时订阅/取消订阅有什么问题吗?我不知道Laravel,因此我可能缺少该范例的正确答案。(
    命令
    类)。但是,只需调用
    Redis::subscribe(['test-channel'],function($message){});
    Redis::unsubscribe(['test-channel'],function($message){})
    应该足够了,不是吗?问题是,当您运行命令时,php脚本将永远运行。一旦启动它,我将如何修改频道?您可以订阅多个频道,包括“客户端控制”频道,甚至“客户端3控制”频道。当您从该频道收到“订阅”或“取消订阅”消息时,您将执行该ac当你收到一条“停止”消息时,你知道要调用Redis::unsubscribe来订阅你订阅的所有频道,并终止该命令(return)。显然,您需要某种存储在某处的状态,甚至可能是在Redis本身中,以允许外部控制器导致这些订阅/取消订阅/停止订阅以获得答案。我不想使用像您这样的SQL数据库,而是想使用Redis缓存。我想知道如何从内部从特定的Redis主题进行sub/unsubMessageComponentInterface我从来没有使用过redis缓存,现在正在研究它,因为你的帖子,如果我找到答案,我会给你回复。尽管上述设置应该为未来的开发者提供参考,他们对如何扩展websocket服务器没有真正的想法。你打算使用redis.io或其他任何东西吗弹力绷带