implement WebSocket with cowboy the main implementation of the following callback function the return value of the following function to specifically figure out the reason reference WebSocket specific protocol is mainly two part handshake and data transmission
-Export([init/3]). common all handler callbacks. To establish a websocket connection , This function must return the upgrade tuple . -Export([websocket_init/3]). the initial socket status can also be used to register the process , start a timer , and so return the reference doc
.
and then WebSocket shook hands . -Export([websocket_handle/3]). Handles the corresponding message sent by the client. Return format reference cow corresponding doc -Export([websocket_info/3]). Processing of messages distributed between Erlang -Export([websocket_terminate/3]). WebSocket Disconnect for finishing work I am here still using OTP to build the entire project main code and effect
-module (websocket_app).-behaviour (application).%%Application Callbacks-export ([start/2, stop/1]).%% ===================================================================%%Application Callbacks%% ===================================================================Start (_starttype, _startargs)-The tree that starts the storage PID can be processed using the ETS form, but for the convenience of cluster processing I use the Mnesia OK=websocket_store:init (),%%Configure Routing Dispatch=Cowboy_router:compile ([{'_', [ {"/", Cowboy_static, {priv_file, WebSocket,"index.html"}}, {"/websocket", Websocket_hander, []}, {"/static/[...]", Cowboy_static, {priv_dir, WebSocket,"Static"}] }]), {OK, _}= Cowboy:start_http (http, -, [{port,8080}], [{env, [{Dispatch, Dispatch}]}],%%Start the Monitoring Tree Websocket_sup:start_link (). Stop (_state)-OK.
-module (websocket_sup).-behaviour (supervisor).%%API-export ([start_link/0]).%%Supervisor Callbacks-export ([init/1]).Percent of Helper macro fordeclaring children of supervisor-define (Child (I, Type), {i, {i, Start_link, []}, Permanent, -, Type, [I]}).%% ===================================================================%%API Functions%% ===================================================================Start_link ()-Supervisor:start_link ({local,? MODULE},?MODULE, []).%% ===================================================================%%Supervisor Callbacks%% ===================================================================init ([])-Children=[], {OK, {{one_for_one,5,Ten}, children}}.
View Code
-module (websocket_hander).-behaviour (Cowboy_websocket_handler).%% ------------------------------------------------------------------%%API Function Exports%% ------------------------------------------------------------------%% ----------------------------------------- -------------------------%%Gen_server Function ExportsPercent-------------------------------------------------------------------export ([init/3]).-export ([websocket_init/3]).-export ([websocket_handle/3]).-export ([websocket_info/3]).-export ([websocket_terminate/3]).%% ------------------------------------------------------------------%%API Function Definitions%% ------------------------------------------------------------------%% ----------------------------------------- -------------------------%%gen_server Function Definitions%% ------------------------------------------------------------------%%websocket handshake init ({TCP, HTTP}, _req, _opts)-Insert Data Websocket_store:dirty_insert (self (), web), {Upgrade, protocol, cowboy_websocket}.%%Connection Initial websocket_init (_transportname, Req, _opts)-send a message after a second connection Erlang:start_timer ( +, self (), <<"hello!">>), {OK, Req, undefined_state}.%%processing the message that the client sends the post Websocket_handle ({text, Msg}, Req, state)-send the message to the rest of the process here can be delivered to the TCP socket can also be delivered websocket so that the service can be implemented to support multi-protocol processing lists:foreach(Fun ([Pid,sockettype]) CaseSocketType of TCP-OK; Web- CasePid = =Self () oftrue-OK; falsepid!{chat,msg} end end End,websocket_store:dirty_look All ()), {reply, {text,<<"That's what she said!", Msg/binary >>}, Req, State};websocket_handle (_data, Req, State)-{OK, Req, state}.Percent processing Erlang sends messages here is to receive $Row sent data websocket_info ({chat,msg},_req,state)-{reply,{text,msg},_req,state};Percent Processing Erlang:start_timer ( +, self (), <<"hello!">>) sent message Websocket_info ({timeout, _ref, Msg}, Req, state)-{reply, {text, Msg}, Req, State};websocket_info (_info, Req, State)-{OK, Req, state}.%%Disconnect Socketwebsocket_terminate (_reason, _req, _state)-Websocket_store:dirty_delete (self ()), OK.%% ------------------------------------------------------------------%%Internal Function Definitions%% ------------------------------------------------------------------
%%%-------------------------------------------------------------------%%% @author ThinkPad <>%%% @copyright ( C the, ThinkPad%%%@doc%%%%%%@end%%% Created: -June theby ThinkPad <>%%%--------------------------------------------------------------------module (websocket_store).-include_lib ("Stdlib/include/qlc.hrl" ).%%API-export ([dirty_insert/2, dirty_lookall/0, dirty_lookall_record/0, dirty_delete/1]).-export ([init/0, insert/2, delete/1, lookup/1, lookall/0]).-record (Socket_to_pid, {pid,socket_type}).-define (Wait_for_tables,10000).%%%===================================================================%%%API%%%===================================================================Init ()-Dynamic_db_init (). %--------------------------------------------------------------------%%@doc Insert a key and PID.Percent @spec Insert (Key, Pid)void()%%@end%%--------------------------------------------------------------------Insert (Pid,sockettype) when Is_pid (Pid)- Fun= Fun ()-Mnesia:write (#socket_to_pid {pid = pid, Socket_type =SocketType}) End, {atomic, _}=mnesia:transaction (fun).%--------------------------------------------------------------------%%@doc Dirty Insert PID and socket%%@spec Dirty_insert (Pid socket)%%@end%%--------------------------------------------------------------------Dirty_insert (Pid,sockettype) when Is_pid (Pid)-Mnesia:dirty_write (#socket_to_pid {pid= Pid, Socket_type =sockettype}).%--------------------------------------------------------------------%%@doc dirty_read Data%%@spec Dirty_lookall ()%%@end%%--------------------------------------------------------------------Dirty_lookall ()-Mnesia:dirty_select (socket_to_pid,[{#socket_to_pid {pid=' $', Socket_type =' $'},[],['$$']}]). Dirty_delete (Pid)-Mnesia:dirty_delete (socket_to_pid,pid).%--------------------------------------------------------------------%%@doc look all record info%%@spec%%@end%%--------------------------------------------------------------------Dirty_lookall_record ()-Mnesia:dirty_select (socket_to_pid,[{#socket_to_pid {pid=' $', Socket_type =' $'},[],['$_']}]).%%--------------------------------------------------------------------%%@doc Find A PID given a key.Percent @spec Lookup (Key), {OK, Pid} |{error, not_found}%%@end%%--------------------------------------------------------------------lookup (Pid)- Do(Qlc:q ([{X#socket_to_pid.pid,x#socket_to_pid.socket_type} | | X <-mnesia:table (socket_to_pid), x#socket_to_pid.pid==Pid]).%%--------------------------------------------------------------------%%@doc Find All listPercent @spec Lookall (), {List} |{error, not_found}%%@end%%--------------------------------------------------------------------Lookall ()- Do(Qlc:q ([[X#socket_to_pid.pid,x#socket_to_pid.socket_type] | | X <-mnesia:table (Socket_to_pid)]).Percent--------------------------------------------------------------------percent @doc Delete an element by PID fromThe registrar.Percent @spec Delete (Pid)void()%%@end%%--------------------------------------------------------------------Delete (Pid)-Try[#socket_to_pid {}= Record] =Mnesia:dirty_read (Socket_to_pid, PID, #socket_to_pid. pid), Mnesia:dirty_delete_object (Record)Catch_c:_e-OK end. %%--------------------------------------------------------------------%%@doc%%@spec%%@end%%--------------------------------------------------------------------%%%====================================== =============================%%%Internal Functions%%%===================================================================Dynamic_db_init ()-Delete_schema (), {Atomic, OK}=mnesia:create_table (Socket_to_pid, [{Attributes, Record_info (fields, Socket_to_pid)}]), OK.%%Deletes a local schema.delete_schema ()-mnesia:stop (), Mnesia:delete_schema ([Node ()]), Mnesia:start (). Do(Query),F= Fun ()qlc:e (Query) end, {Atomic, Value}=mnesia:transaction (F), Value.