主页

索引

模块索引

搜索页面

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}.

主页

索引

模块索引

搜索页面