在Erlang的聊天室与牛仔和WebSocket

afdcj2ne  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(184)

我正在尝试创建一个聊天室与牛仔WebSocket处理程序。我希望那些来自每个消息将被转发到其他套接字以及,就像一个聊天组。我不知道如何实现这一点?我不知道如何保存套接字连接到websocket,以便我们可以发送消息给他们。我有这个牛仔处理程序:

-module(chat_conn).

-export([ init/2
    , websocket_init/1
    , websocket_handle/2
    , websocket_info/2
    , terminate/3
    ]).

-include("chat.hrl").

init(Req, [WsConnIdleTimeout]) ->
    ?LOG_DEBUG("[CHAT-CONN] New HTTP Request on: /api , Pid: ~p", [self()]),
    WsOpts = #{idle_timeout => WsConnIdleTimeout},
    State = #{counter => 0},
    {cowboy_websocket, Req, State, WsOpts}.

websocket_init(State0) ->
    ?LOG_DEBUG("[FOOZI-CONN] HTTP Upgraded to WebSocketm pid: ~p", [self()]),
    NewState = State0,
    {ok, NewState}.

websocket_handle({text, PlainRequest}, #{counter := Counter0} = State) ->
    ?LOG_DEBUG("[HIGGS-CONN] Receive New Message: ~p, Pid: ~p" , [PlainRequest, self()]),
    NewCounter = Counter0 + 1,
    Reply = list_to_binary("Counter is: " ++ integer_to_list(NewCounter)),
    NewState = #{counter => NewCounter},
    {reply, {text, Reply}, NewState};
    %{ok, State};
websocket_handle(Frame, State) ->
    ?LOG_INFO("[HIGGS-CONN] Invalid Frame => ~p", [Frame]),
    {stop, State}.

websocket_info(Message, State) ->
    ?LOG_INFO("[CONN-INFO] Unhandled message! => Message: ~p", [Message]),
    {reply, {text, list_to_binary(Message)}, State}.
    %{ok, State}.

terminate(Reason, _, State) ->
    ?LOG_INFO("[CONN-TERMINATE] Terminated! => Pid: ~p, Reason: ~p, State: ~p", [self(), Reason, State]),
    ok.
ukdjmx9f

ukdjmx9f1#

我不知道如何保存连接到websocket的套接字,以便向它们发送消息
在erlang中,gen_servers可以用来存储状态,因此您可以创建一个gen_server,websocket处理程序使用它来保存客户机pid。当客户机使用特定的路由向您的cowboy服务器发送"开始聊天"消息时,将调用关联的websocket处理程序。在该处理程序中,self()将是该客户端的websocket进程的pid。您可以通过调用gen_server:cast(chat_room, {arrive, self()})将该pid保存在gen_server中,然后在x1M4N1x内将PID添加到存储在x1M5N1x变量中的PID列表。
当cowboy服务器从客户端浏览器接收到聊天消息时,客户端的websocket进程将处理该消息,在相应的websocket处理程序中,您可以查询gen_server以获得已连接客户端的pid列表。然后,您可以使用!向每个客户端发送消息。依次,每个客户端的websocket_info()处理程序将处理该消息。它可以通过返回以下内容通过WebSocket将其中继回客户端:{reply, {text, Text}, State}.
对于您的gen_server,您还需要实现一个leave()函数,相应的websocket处理程序将调用该函数来更新存储在gen_server中的客户端列表,例如gen_server:cast(chat_room, {leave, self()})

相关问题