cowboy_websocket ##################### init:: init(Req, State) -> {cowboy_websocket, Req, State}. Subprotocol:: //client可解析基于Websocket的两种子协议STOMP和MQTT,提供header: sec-websocket-protocol: v12.stomp, mqtt //sever只能解析mqtt: sec-websocket-protocol: mqtt % 实例: init(Req0, State) -> case cowboy_req:parse_header(<<"sec-websocket-protocol">>, Req0) of undefined -> {cowboy_websocket, Req0, State}; Subprotocols -> case lists:keymember(<<"mqtt">>, 1, Subprotocols) of true -> Req = cowboy_req:set_resp_header(<<"sec-websocket-protocol">>, <<"mqtt">>, Req0), {cowboy_websocket, Req, State}; false -> Req = cowboy_req:reply(400, Req0), {ok, Req, State} end end. Post-upgrade initialization:: websocket处理connection and requests的是两个不同进程 @xinxi说: 其实这儿已经把websocket的连接了请求分开了 init/2用于处理request websocket_用于处理connetction websocket_init/1: websocket_init(State) -> erlang:start_timer(1000, self(), <<"Hello!">>), {ok, State}. websocket_init(State) -> {reply, {text, <<"Hello!">>}, State}. Receiving frames:: websocket_handle/2: % text, binary, ping or pong websocket_handle(Frame = {text, _}, State) -> {reply, Frame, State}; websocket_handle(_Frame, State) -> {ok, State}. Receiving Erlang messages:: websocket_info/2: websocket_info(Text, State) -> {reply, {text, Text}, State}; websocket_info(_Info, State) -> {ok, State}. Sending frames:: 所有websocket_回调共享返回值 // 发送0帧(frame) websocket_info(_Info, State) -> {ok, State}. // 发送1帧 websocket_info(_Info, State) -> {reply, {text, <<"Hello!">>}, State}. // 发送多帧 websocket_info(_Info, State) -> {reply, [ {text, "Hello"}, {text, <<"world!">>}, {binary, <<0:8000>>} ], State}. Keeping the connection alive:: cowboy会自动回应client发来的ping帧,但还是会把信息转发给handler,但不需要再处理 % 设立连接超时,默认60000(60s) init(Req, State) -> {cowboy_websocket, Req, State, #{idle_timeout => 30000}}. Limiting frame sizes:: % 暂没有默认值 init(Req, State) -> {cowboy_websocket, Req, State, #{max_frame_size => 8000000}}. Saving memory:: websocket_init(State) -> {ok, State, hibernate}. websocket_handle(_Frame, State) -> {ok, State, hibernate}. websocket_info(_Info, State) -> {reply, {text, <<"Hello!">>}, State, hibernate}. hibernate影响: 1. reduce the memory usage 2. increase in the CPU usage or latency can be observed instead, in particular for the more busy connections Closing the connection:: websocket_info(_Info, State) -> {stop, State}. % with reason websocket_info(_Info, State) -> {reply, {close, 1000, <<"some-reason">>}, State}.