使用cowboy实现websocket主要实现以下回调函数 下面的函数返回值要具体弄清楚原因参考 websocket具体协议  主要就是两个部分 握手和数据传输
  -export([init/3]). 常见所有处理程序回调。建立WebSocket连接,这个函数必须返回 upgrade 的元组。
  -export([websocket_init/3]). 初始socket状态,也可以用于注册的过程,启动一个定时器,等返回参考doc.然后和WebSocket握手。
  -export([websocket_handle/3]).处理客户端发送的对应的消息。返回格式 参考cow对应doc
  -export([websocket_info/3]). 处理erlang之间派发的消息
  -export([websocket_terminate/3]). websocket 断开 用于扫尾工作处理
我在这里还是采用otp方式构建整个项目 主要代码 以及效果
-module(websocket_app).

-behaviour(application).

%% Application callbacks
-export([start/, stop/]). %% ===================================================================
%% Application callbacks
%% =================================================================== start(_StartType, _StartArgs) ->
%%启动存储pid的树据 可以采用 ets 表格处理 但是为了方便集群处理 我采用的mnesia
ok = websocket_store:init(),
%% 配置路由
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, }],
[{env, [{dispatch, Dispatch}]}]),
%%启动监督树
websocket_sup:start_link(). stop(_State) ->
ok.
-module(websocket_sup).

-behaviour(supervisor).

%% API
-export([start_link/]). %% Supervisor callbacks
-export([init/]). %% Helper macro for declaring 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, , }, Children} }.
-module(websocket_hander).

-behaviour(cowboy_websocket_handler).

%% ------------------------------------------------------------------
%% API Function Exports
%% ------------------------------------------------------------------ %% ------------------------------------------------------------------
%% gen_server Function Exports
%% ------------------------------------------------------------------ -export([init/]).
-export([websocket_init/]).
-export([websocket_handle/]).
-export([websocket_info/]).
-export([websocket_terminate/]). %% ------------------------------------------------------------------
%% API Function Definitions
%% ------------------------------------------------------------------ %% ------------------------------------------------------------------
%% gen_server Function Definitions
%% ------------------------------------------------------------------ %%websocket 握手
init({tcp, http}, _Req, _Opts) ->
%%插入数据
websocket_store:dirty_insert(self(),web),
{upgrade, protocol, cowboy_websocket}.
%%连接初始
websocket_init(_TransportName, Req, _Opts) ->
%%连接一秒后 发送消息
erlang:start_timer(, self(), <<"Hello!">>),
{ok, Req, undefined_state}.
%%处理客户端发送投递的消息
websocket_handle({text, Msg}, Req, State) ->
%% 把消息投递到其余的进程 这里可以 投递到 tcp socket 也可以投递的 websocket 这样就可以实现 服务支持多协议处理
lists:foreach(fun([Pid,SocketType]) ->
case SocketType of
tcp -> ok;
web ->
case Pid == self() of
true -> ok;
false -> Pid!{chat,Msg}
end
end
end,websocket_store:dirty_lookall()),
{reply, {text, << "That's what she said! ", Msg/binary >>}, Req, State};
websocket_handle(_Data, Req, State) ->
{ok, Req, State}.
%% 处理erlang 发送的消息 这里是接收 行发送的数据
websocket_info({chat,Msg},_Req,State)->
{reply,{text,Msg},_Req,State};
%% 处理 erlang:start_timer(, self(), <<"Hello!">>) 发送的消息
websocket_info({timeout, _Ref, Msg}, Req, State) ->
{reply, {text, Msg}, Req, State}; websocket_info(_Info, Req, State) ->
{ok, Req, State}.
%%断开socket
websocket_terminate(_Reason, _Req, _State) ->
websocket_store:dirty_delete(self()),
ok. %% ------------------------------------------------------------------
%% Internal Function Definitions
%% ------------------------------------------------------------------
%%%-------------------------------------------------------------------
%%% @author thinkpad <>
%%% @copyright (C) , thinkpad
%%% @doc
%%%
%%% @end
%%% Created : Jun by thinkpad <>
%%%-------------------------------------------------------------------
-module(websocket_store). -include_lib("stdlib/include/qlc.hrl" ).
%% API
-export([dirty_insert/,dirty_lookall/,dirty_lookall_record/,dirty_delete/]). -export([init/,insert/,delete/,lookup/,lookall/]). -record(socket_to_pid, {pid,socket_type}). -define(WAIT_FOR_TABLES, ). %%%===================================================================
%%% API
%%%===================================================================
init()->
dynamic_db_init(). %--------------------------------------------------------------------
%% @doc Insert a key and pid.
%% @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='$1',socket_type = '$2'},[],['$$']}]). 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='$1',socket_type = '$2'},[],['$_']}]).
%%--------------------------------------------------------------------
%% @doc Find a pid given a key.
%% @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 list
%% @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)])). %%--------------------------------------------------------------------
%% @doc Delete an element by pid from the registrar.
%% @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.

cowboy实现websocket的更多相关文章

  1. Cowboy 开源 WebSocket 网络库

    Cowboy.WebSockets 是一个托管在 GitHub 上的基于 .NET/C# 实现的开源 WebSocket 网络库,其完整的实现了 RFC 6455 (The WebSocket Pro ...

  2. 【转】Cowboy 开源 WebSocket 网络库

    原文链接: http://www.cnblogs.com/gaochundong/p/cowboy_websockets.html

  3. [Erlang33]使用recon从网页查看Erlang运行状态

    0.需求分析 Erlang最好的卖点之一就是提供了一个非常强大的shell来查看Node运行时的各种状态,可以进行各种各样的内部查看,在运行时调试和分析,热更新代码.   但是总有一些在生产环境下要慎 ...

  4. Erlang cowboy websocket 服务器

    Erlang cowboy websocket 服务器 原文见于: http://marcelog.github.io/articles/erlang_websocket_server_cowboy_ ...

  5. Cowboy http服务器 websocket

    一.基础介绍 cowboy是一个小巧.快速.模块化的http服务器,采用Erlang开发.其中良好的clean module使得我们可以扩展到多种网络协议之中,cowboy自带的有tcp和ssl,而也 ...

  6. [翻译][erlang]cowboy handler模块的使用

    关于Cowboy Cowboy是基于Erlang实现的一个轻量级.快速.模块化的http web服务器. Handlers,用于处理HTTP请求的程序处理模块. Plain HTTP Handlers ...

  7. Erlang cowboy 入门参考之现代Web的发展历史

    Erlang cowboy 入门参考之现代Web发展史 原文: http://ninenines.eu/docs/en/cowboy/1.0/guide/modern_web/ 让我回顾一下web技术 ...

  8. Erlang cowboy 入门参考

    Erlang cowboy 入门参考 cheungmine,2014-10-28 本文翻译自: http://ninenines.eu/docs/en/cowboy/HEAD/guide/gettin ...

  9. 带ssl的websocket例子

    还是在那个websocket_demo的例子 rebar-creator create-app websocket_demo tree一下看看大概目录 ├── cert │   ├── cowboy- ...

随机推荐

  1. 了解IE中filter属性的应用!

    在设置不透明属性时,经常用opacity来增加层次感或者增加用户体验,但这个属性是css3属性,对于低级浏览器的兼容性来说就达不到预期的效果. 一般而言,我们都尽可能少用一些浏览私有属性-webkit ...

  2. mapreduce编程--(准备篇)

    mapreduce编程准备 学习mapreduce编程之前需要做一些概念性的了解,这是做的一些课程学习笔记,以便以后时不时的翻出来学习下,之前看过一篇文章大神们都是时不时的翻出基础知识复习下,我也做点 ...

  3. 负载均衡集群ipvsadm命令及基本用法

    ipvsadm是LVS在应用层的管理命令,我们可以通过这个命令去管理LVS的配置.需要使用yum单独安装. 基本用法: ipvsadm COMMAND [protocol] service-addre ...

  4. 深入解析Koa之核心原理

    这篇文章主要介绍了玩转Koa之核心原理分析,本文从封装创建应用程序函数.扩展res和req.中间件实现原理.异常处理的等这几个方面来介绍,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参 ...

  5. jQuery多级联动美化版Select下拉框

    在线演示 本地下载

  6. Win32 API编程:网络编程在设置WSAAsyncSelect模型后connect的返回值问题

    通过WSAAsyncSelect()可以设置非阻塞异步套接字 ::WSAAsyncSelect(s, hDlg, WM_SOCKET, FD_CONNECT | FD_CLOSE | FD_WRITE ...

  7. C++中 int main(int argc, char **argv) 命令行传递参数

    C++中,比较常见的是不带参数的主函数int main(),如果使用命令行执行程序,主函数也可以接收预先输入的参数,形式如下. int main(int argc,char **argv) argc: ...

  8. Spring MVC执行原理和基于Java的配置过程

    一.Spring MVC执行原理和基于Java配置的配置过程 (一)Spring MVC执行过程,大致为7步. 所有的请求都会经过Spring的一个单例的DispacherServlet. Dispa ...

  9. Kruskal算法-最小生成树

    2017-07-26  10:32:07 writer:pprp Kruskal算法是根据边的加权值以递增的方式,一次找出加权值最低的边来建最小生成树:并且每次添加的边不能造成生成树有回路,直到找到N ...

  10. DIKW:数据、信息、知识、智慧的金字塔层次体系

    http://www.ciotimes.com/ProCase/85417.html 前言 知识对于个人.组织的重要性已经不言而喻.可以说,管理与应用知识的能力已经成为企业的核心竞争力. 知识如此重要 ...