Интерфейс Phoenix в режиме реального времени построен на двух открытых по умолчанию абстракциях - интерфейсе сокетов, через который соединяется клиент - обычно это веб-сокет (хотя он может использовать длинные запросы или использовать другие транспорты), это «провод»"Это создано между клиентом и вашим сервером.Обычно вы опосредуете это соединение с помощью токена, чтобы решить, сможет ли клиент открыть это сокетное соединение.Он указан в user_socket.ex
.
. И тогда у вас есть интерфейс канала, который является gen_server с определенными дескрипторами (api), предназначенными для приема входящих сообщений через «провод».Вы также можете иметь логику авторизации для разрешения подписки на канал («присоединение»), и она может варьироваться в зависимости от канала (или даже темы).
Каждый клиент может быть подключен к 1 сокету и от 0 до N каналов.Клиент, подключенный к каналу внизу, просто (упрощенно) регистрирует данный сокет в интерфейсе подписчика издателя (PubSub Phoenix) и имеет процесс для этих «channel: room» для каждого сокета, подписанного на эту конкретную комбинацию.
Если вы запустите :observer.start
из вашей оболочки iex
и перейдете на вкладку Processes
, а затем присоединитесь от двух разных клиентов к одному и тому же «каналу: теме», который вы увидите, там будетбыть двухканальными процессами, а не одним.Если вы видите дерево приложений из Elixir.YourWeb.PubSub.Local0, вы также увидите 2 процесса, «подключенных» к нему или из него.
Это означает, что когда вы запускаете channel.leave()
со своегоВ конце концов, ваш сервер отписывает этого клиента от «канала», который вы только что «ушли», и процесс, который обрабатывал его, закрывается.Выход из канала - отмена подписки определенного сокета (клиента) из этой конкретной комбинации channel:topic
.Это не мешает другим клиентам, связанным с той же темой.В этом случае розетка («провод») все еще подключена.Вы можете повторно присоединиться к каналу или присоединиться к другим без необходимости «просить» (вести переговоры), чтобы снова подключиться к сокету.
С другой стороны, если вы выдаете socket.disconnect()
, вы «отключаете провод» и, следовательно, отмените подписку на этот конкретный сокет (клиент) со всех каналов, на которые он был ранее подписан.Это отключает все процессы, связанные с данным сокетом, но также не мешает сокетам / соединениям / подпискам других клиентов.
Если все клиенты покидают данный канал (либо через «уйти», либо «отключиться»)Приведя их сокеты), вы увидите, что для данного канала не будет запущен процесс.Как только другой клиент присоединяется к этому каналу, создается процесс для этого конкретного клиента и канала: тема.
tldr;чтобы ответить на ваш вопрос:
Но если выу вас есть долго выполняющиеся процессы, которые порождаются изнутри самого канала, которые должны быть закрыты, когда ни один клиент не подключен к этому конкретному каналу: тема, тогда вам, конечно, нужно будет их очистить.Помимо обычных возможностей мониторинга Erlang, Phoenix имеет интерфейс присутствия, который также позволяет отслеживать это.