Я делаю следующее:
Когда пользователь подключается к сайту, я меняю gen_server, представляющий пользователя. Затем генеральный сервер регистрируется в gproc как {n, l, {user, UserName}}. (Он может регистрировать такие свойства, как {p, l, {chat, ChannelID}} для прослушивания каналов чата. (См. gproc pub / sub))
Итак, теперь соединение пользователя с веб-сокетом запускает обработчик ковбоя (я использую Bullet). Обработчики запрашивают у gproc pid () gen_server пользователя и регистрируются как получатель сообщений. Итак, теперь, когда пользователь gen_server получает сообщения, он перенаправляет их обработчику веб-сокета.
Когда соединение с веб-сокетом завершается, обработчик отменяет регистрацию от пользователя gen_server, поэтому пользователь gen_server будет хранить сообщения до следующего соединения или следующего тайм-аута. По истечении времени ожидания вы можете просто завершить работу сервера (сообщения будут потеряны, но это нормально).
Смотрите: (не проверено)
-module(user_chat).
-record(state, {mailbox,receiver=undefined}).
-export([start_link/1,set_receiver/1,unset_receiver/1]).
%% API
start_link(UserID) ->
gen_server:start_link(?MODULE,[UserID],[]).
set_receiver(UserID) ->
set_receiver(UserID,self()).
unset_receiver(UserID) ->
%% Just set the receiver to undefined
set_receiver(UserID,undefined).
set_receiver(UserID, ReceiverPid) ->
UserPid = gproc:where({n,l,UserID}),
gen_server:call(UserPid,{set_receiver,ReceiverPid}).
%% Gen server internals
init([UserID]) ->
gproc:reg({n,l,{user,UserID}}),
{ok,#state{mailbox=[]}}.
handle_call({set_receiver,ReceiverPid},_From,#state{mailbox=MB}=State) ->
NewMB = check_send(MB,State),
{reply,ok,State#state{receiver=ReceiverPid,mailbox=NewMB}}.
handle_info({chat_msg,Message},#state{mailbox=MB}=State) ->
NewMB = check_send([Message|MB],State),
{noreply, State#state{mailbox=NewMB}}.
%% Mailbox empty
check_send([],_) -> [];
%% Receiver undefined, keep messages
check_send(Mailbox,#state{receiver=undefined}) -> Mailbox
%% Receiver is a pid
check_send(Mailbox,#state{receiver=Receiver}) when is_pid(Receiver) ->
%% Send all messages
Receiver ! {chat_messages,Mailbox},
%% Then return empty mailbox
[].
person
lud
schedule
05.08.2013