From 8404b1c908ac890925496ce839e5b2b2b407a6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 11 Sep 2018 14:33:58 +0200 Subject: Add a commands-based interface to Websocket handlers This feature is currently experimental. It will become the preferred way to use Websocket handlers once it becomes documented. A commands-based interface enables adding commands without having to change the interface much. It mirrors the interface of stream handlers or gen_statem. It will enable adding commands that have been needed for some time but were not implemented for fear of making the interface too complex. --- test/handlers/ws_handle_commands_h.erl | 31 +++++++++++++++++++++++++++++++ test/handlers/ws_info_commands_h.erl | 32 ++++++++++++++++++++++++++++++++ test/handlers/ws_init_commands_h.erl | 30 ++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 test/handlers/ws_handle_commands_h.erl create mode 100644 test/handlers/ws_info_commands_h.erl create mode 100644 test/handlers/ws_init_commands_h.erl (limited to 'test/handlers') diff --git a/test/handlers/ws_handle_commands_h.erl b/test/handlers/ws_handle_commands_h.erl new file mode 100644 index 0000000..da3ffad --- /dev/null +++ b/test/handlers/ws_handle_commands_h.erl @@ -0,0 +1,31 @@ +%% This module takes commands from the x-commands header +%% and returns them in the websocket_handle/2 callback. + +-module(ws_handle_commands_h). +-behavior(cowboy_websocket). + +-export([init/2]). +-export([websocket_init/1]). +-export([websocket_handle/2]). +-export([websocket_info/2]). + +init(Req=#{pid := Pid}, RunOrHibernate) -> + Commands0 = cowboy_req:header(<<"x-commands">>, Req), + Commands = binary_to_term(base64:decode(Commands0)), + case Commands of + bad -> ct_helper_error_h:ignore(Pid, cowboy_websocket, handler_call, 6); + _ -> ok + end, + {cowboy_websocket, Req, {Commands, RunOrHibernate}}. + +websocket_init(State) -> + {[], State}. + +websocket_handle(_, State={Commands, run}) -> + {Commands, State}; +websocket_handle(_, State={Commands, hibernate}) -> + {Commands, State, hibernate}. + +websocket_info(_, State) -> + {[], State}. + diff --git a/test/handlers/ws_info_commands_h.erl b/test/handlers/ws_info_commands_h.erl new file mode 100644 index 0000000..d596473 --- /dev/null +++ b/test/handlers/ws_info_commands_h.erl @@ -0,0 +1,32 @@ +%% This module takes commands from the x-commands header +%% and returns them in the websocket_info/2 callback. +%% This callback is triggered via a message. + +-module(ws_info_commands_h). +-behavior(cowboy_websocket). + +-export([init/2]). +-export([websocket_init/1]). +-export([websocket_handle/2]). +-export([websocket_info/2]). + +init(Req=#{pid := Pid}, RunOrHibernate) -> + Commands0 = cowboy_req:header(<<"x-commands">>, Req), + Commands = binary_to_term(base64:decode(Commands0)), + case Commands of + bad -> ct_helper_error_h:ignore(Pid, cowboy_websocket, handler_call, 6); + _ -> ok + end, + {cowboy_websocket, Req, {Commands, RunOrHibernate}}. + +websocket_init(State) -> + self() ! shoot, + {[], State}. + +websocket_handle(_, State) -> + {[], State}. + +websocket_info(_, State={Commands, run}) -> + {Commands, State}; +websocket_info(_, State={Commands, hibernate}) -> + {Commands, State, hibernate}. diff --git a/test/handlers/ws_init_commands_h.erl b/test/handlers/ws_init_commands_h.erl new file mode 100644 index 0000000..8bae352 --- /dev/null +++ b/test/handlers/ws_init_commands_h.erl @@ -0,0 +1,30 @@ +%% This module takes commands from the x-commands header +%% and returns them in the websocket_init/1 callback. + +-module(ws_init_commands_h). +-behavior(cowboy_websocket). + +-export([init/2]). +-export([websocket_init/1]). +-export([websocket_handle/2]). +-export([websocket_info/2]). + +init(Req=#{pid := Pid}, RunOrHibernate) -> + Commands0 = cowboy_req:header(<<"x-commands">>, Req), + Commands = binary_to_term(base64:decode(Commands0)), + case Commands of + bad -> ct_helper_error_h:ignore(Pid, cowboy_websocket, handler_call, 6); + _ -> ok + end, + {cowboy_websocket, Req, {Commands, RunOrHibernate}}. + +websocket_init(State={Commands, run}) -> + {Commands, State}; +websocket_init(State={Commands, hibernate}) -> + {Commands, State, hibernate}. + +websocket_handle(_, State) -> + {[], State}. + +websocket_info(_, State) -> + {[], State}. -- cgit v1.2.3