From 3c4409140cf76f1d08750f8452b8e950bce02dd9 Mon Sep 17 00:00:00 2001 From: Werner Date: Tue, 19 Apr 2022 17:44:53 -0300 Subject: [PATCH] Update events --- broken/chat.js | 38 ++++++++++++++++++++ broken/chat_room.erl | 84 ++++++++++++++++++++++++++++++++++++++++++++ broken/erws_app.erl | 15 ++++++++ broken/erws_sup.erl | 28 +++++++++++++++ broken/index.html | 55 +++++++++++++++++++++++++++++ broken/ws_h.erl | 29 +++++++++++++++ priv/index.html | 33 +++++++++-------- src/erws_app.erl | 7 +--- src/erws_sup.erl | 9 ----- src/ws_h.erl | 6 ++-- 10 files changed, 269 insertions(+), 35 deletions(-) create mode 100644 broken/chat.js create mode 100644 broken/chat_room.erl create mode 100644 broken/erws_app.erl create mode 100644 broken/erws_sup.erl create mode 100644 broken/index.html create mode 100644 broken/ws_h.erl diff --git a/broken/chat.js b/broken/chat.js new file mode 100644 index 0000000..0a68937 --- /dev/null +++ b/broken/chat.js @@ -0,0 +1,38 @@ +var socket; + +function add_message(message) { + $('#messages').append('

').children().last().text(message); +} + +function read_message_input() { + return $('#message').val(); +} + +function connect_to_chat() { + + socket = new WebSocket("ws://localhost:8080/ws"); + + socket.onopen = function () { + add_message("Connected.") + }; + + socket.onmessage = function (event) { + add_message(event.data); + }; + + socket.onclose = function () { + add_message("Connection closed."); + }; +} + +function send_message(e) { + var message = read_message_input(); + add_message(message); + socket.send(message); + $('#message').val(""); +} + +$(document).ready(function () { + connect_to_chat(); + $('#send-button').click(send_message); +}) diff --git a/broken/chat_room.erl b/broken/chat_room.erl new file mode 100644 index 0000000..5c1fc0c --- /dev/null +++ b/broken/chat_room.erl @@ -0,0 +1,84 @@ +-module(chat_room). +-behaviour(gen_server). + +-export([start_link/0, enter/1, leave/1, send_message/2]). + +%% gen_server callbacks +-export([ + init/1, + handle_call/3, + handle_cast/2, + handle_info/2, + terminate/2, + code_change/3 +]). + +-define(SERVER, ?MODULE). + +-record(state, {clients = []}). + +%%%============================================================================= +%%% API +%%%============================================================================= + +start_link() -> + gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). + +enter(Pid) -> + gen_server:cast(?SERVER, {enter, Pid}). + +leave(Pid) -> + gen_server:cast(?SERVER, {leave, Pid}). + +send_message(Pid, Message) -> + gen_server:cast(?SERVER, {send_message, Pid, Message}). + +%%%============================================================================= +%%% gen_server callbacks +%%%============================================================================= + +init([]) -> + Dispatch = cowboy_router:compile([ + {'_', [ + {"/", cowboy_static, {priv_file, erws, "index.html"}}, + {"/ws", ws_h, []}, + {"/static/[...]", cowboy_static, {priv_dir, erws, "static"}} + ]} + ]), + cowboy:start_clear(http, [{port, 8080}], #{ + env => #{dispatch => Dispatch} + }), + {ok, #state{}}. + +handle_call(_Request, _From, State) -> + {noreply, State}. + +handle_cast({enter, Pid}, State = #state{clients = Clients}) -> + {noreply, State#state{clients = [Pid | Clients]}}; +handle_cast({leave, Pid}, State = #state{clients = Clients}) -> + {noreply, State#state{clients = Clients -- [Pid]}}; +handle_cast({send_message, Pid, Message}, State) -> + do_send_message(Pid, Message, State), + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + cowboy:stop_listener(chat). + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%%============================================================================= +%%% Internal functions +%%%============================================================================= + +do_send_message(Pid, Message, #state{clients = Clients}) -> + OtherPids = Clients -- [Pid], + lists:foreach( + fun(OtherPid) -> + OtherPid ! {send_message, self(), Message} + end, + OtherPids + ). diff --git a/broken/erws_app.erl b/broken/erws_app.erl new file mode 100644 index 0000000..6b4ae6f --- /dev/null +++ b/broken/erws_app.erl @@ -0,0 +1,15 @@ +%% Feel free to use, reuse and abuse the code in this file. + +%% @private +-module(erws_app). +-behaviour(application). + +%% API. +-export([start/2, stop/1]). + +%% API. +start(_Type, _Args) -> + erws_sup:start_link(). + +stop(_State) -> + ok = cowboy:stop_listener(http). diff --git a/broken/erws_sup.erl b/broken/erws_sup.erl new file mode 100644 index 0000000..18068a2 --- /dev/null +++ b/broken/erws_sup.erl @@ -0,0 +1,28 @@ +%% Feel free to use, reuse and abuse the code in this file. + +%% @private +-module(erws_sup). +-behaviour(supervisor). + +%% API +-export([start_link/0]). + +%% Supervisor callbacks +-export([init/1]). + +%% Helper macro for declaring children of supervisor +-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}). + +%% =================================================================== +%% API functions +%% =================================================================== + +start_link() -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +%% =================================================================== +%% Supervisor callbacks +%% =================================================================== + +init([]) -> + {ok, {{one_for_one, 5, 10}, [?CHILD(chat_room, worker)]}}. diff --git a/broken/index.html b/broken/index.html new file mode 100644 index 0000000..420cf1d --- /dev/null +++ b/broken/index.html @@ -0,0 +1,55 @@ + + + + + Chat room application + + + + + + +
+ + + + + \ No newline at end of file diff --git a/broken/ws_h.erl b/broken/ws_h.erl new file mode 100644 index 0000000..ff70f2c --- /dev/null +++ b/broken/ws_h.erl @@ -0,0 +1,29 @@ +-module(ws_h). + +-export([init/2]). +-export([websocket_init/1]). +-export([websocket_handle/3]). +-export([websocket_info/3]). +-export([websocket_terminate/3]). + +init(Req, Opts) -> + {cowboy_websocket, Req, Opts}. + +websocket_init(Req) -> + chat_room:enter(self()), + {ok, Req}. + +websocket_handle({text, Msg}, Req, State) -> + chat_room:send_message(self(), Msg), + {ok, Req, State}; +websocket_handle(_Data, Req, State) -> + {ok, Req, State}. + +websocket_info({send_message, _ServerPid, Msg}, Req, State) -> + {reply, {text, Msg}, Req, State}; +websocket_info(_Info, Req, State) -> + {ok, Req, State}. + +websocket_terminate(_Reason, _Req, _State) -> + chat_room:leave(self()), + ok. diff --git a/priv/index.html b/priv/index.html index 24d9587..c23c717 100644 --- a/priv/index.html +++ b/priv/index.html @@ -3,42 +3,41 @@ - Websocket client + Erlang WebSocket
-

Websocket client

+

Erlang WebSocket

- +