首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Flash >

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

2012-08-13 
[dika 记录]cowboy 扩展socket 协议,以解决flash ,erlang通讯的沙箱为例子cowboy 的 acceptor pool是通用

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


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


热点排行