cowboy 的 acceptor pool是通用的,而且说实话,acceptor pool的写法都那样,学习是可以的,但是没必要重复造轮子了.
记录一下 直接使用cowboy做底层socket设施:
把cowboy的依赖打上,我是用rebar的,deps上加上cowboy的git, 可以直接下载源码,放到自己项目中.
要使用很简单,启动cowboy listener 并指定 要回调的协议处理模块.
我就分了两个文件,dp_socket_service.erl dp_proto_handler.erl .
开始先介绍比较通用部分的写法,后面再加入flash沙箱策略文件的socket例子
dp_socket_service.erl 使用了gen_server ,目的只是启动了,cowboy listener
这里没有什么特别,下面开始写协议处理模块.
init([]) ->
cowboy:start_listener(dp_listener, 100,
cowboy_tcp_transport, [{port,88}],
dp_proto_handler,[]
).
cowboy 有定义了behaviour
-module(cowboy_protocol).
-export([behaviour_info/1]).
%% @private
-spec behaviour_info(_)->undefined | [{start_link, 4}, ...].
behaviour_info(callbacks) ->
[{start_link, 4}];
behaviour_info(_Other) ->
undefined.
可见,要暴露的start_link/4的接口即可, 而四个参数是什么? 最简单办法就是打开cowboy_http_protocol.erl看看
-spec start_link(pid(), inet:socket(), module(), any()) ->{ok, pid()}.
start_link(ListenerPid, Socket, Transport, Opts) ->
这样很清晰了.可以动手了
dp_proto_handler.erl
-spec start_link(pid(), ssl:sslsocket(), module(), []) ->;{ok, pid()}.
start_link(_ListenerPid, Socket, Transport, []) ->;
Pid = spawn_link(?MODULE, init, [Socket, Transport]),
{ok, Pid}.
init(Socket, Transport) ->
recv(#state{socket=Socket, transport=Transport}),
ok.
把一些我不需要的参数忽略了.开了个进程来处理
recv就是负责处理包的,下面写法有两种了.
一,调用Transport的方法,其实就是调用gen_tcp
二,用receive 原语
-------------------------------------------------以flash 沙箱策略文件为例子--------------------------------------------------------
先定义了这次的请求把,
-define(FLASH_REQ, <<"<policy-file-request/>\0">>). %%这里记得是后面 \0补全阿
-define(FLASH_FILE, <<"<cross-domain-policy><allow-access-from domain='*' to-ports='*' /></cross-domain-policy>">>).
第一种,直接调用Transport的方法收包发包.
recv(#state{socket=Socket, transport=Transport})->
case Transport:recv(Socket, 0, 5000) of
{ok, ?FLASH_REQ}->Transport:send(Socket,?FLASH_FILE),terminate();
{ok,Other}-> ok;
{error, _Reason} -> terminate()
end.
第二种,receive原句
recv(#state{socket=Socket, transport=Transport})->
Transport:setopts(Socket, [{active, once}]),
receive
{ok, ?FLASH_REQ}->Transport:send(Socket,?FLASH_FILE),terminate();
{ok,Other}-> ok;
{error, _Reason} -> terminate()
end.
总结,用法跟直接用tcp都差不多.
by dp~~
本文档介绍了如何利用Cowboy框架扩展socket协议,以解决Flash与Erlang之间的通信问题。首先,介绍了如何配置和启动Cowboy监听器,并定义了一个协议处理模块。接着展示了两种不同的接收和发送数据的方法,包括直接调用Transport的方法和使用receive原语。通过示例代码,解释了如何处理Flash的策略文件请求并发送响应。
1280

被折叠的 条评论
为什么被折叠?



