[dika 记录] cowboy 扩展socket 协议, 以解决flash ,erlang通讯的沙箱为例子

本文档介绍了如何利用Cowboy框架扩展socket协议,以解决Flash与Erlang之间的通信问题。首先,介绍了如何配置和启动Cowboy监听器,并定义了一个协议处理模块。接着展示了两种不同的接收和发送数据的方法,包括直接调用Transport的方法和使用receive原语。通过示例代码,解释了如何处理Flash的策略文件请求并发送响应。


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看看


%% @doc Start an HTTP protocol process.
-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~~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值