一个完整的Erlang应用
http://blog.chinaunix.net/uid-25876834-id-3308693.html
这里介绍构建一个完整的Erlang/OTP应用的例子,最后还给出了一个在实际生成环境中,如何启动应用的才能方便运维人员维护和部署的实例。例子摘自 《Manning.Erlang.and.OTP.in.Action》(国内目前已经有中文版发行)。
点击(此处)折叠或打开
- {application,tcp_rpc,
- [{description,"RPC Server for Erlang and OTP in action"},
- {vsn, "0.1.0"},
- {modules,[tr_app,
- tr_sup,
- tr_server]},
- {registered, [tr_sup]},
- {applications, [kernel, stdlib]},
- {mod, {tr_app, []}}
- ]}.
2、应用启动模块 tr_app.erl
点击(此处)折叠或打开
- -module(tr_app).
- -behaviour(application).
- %% --------------------------------------------------------------------
- %% Include files
- %% --------------------------------------------------------------------
- %% --------------------------------------------------------------------
- %% Behavioural exports
- %% --------------------------------------------------------------------
- -export([
- start/2,
- stop/1
- ]).
- %% --------------------------------------------------------------------
- %% Internal exports
- %% --------------------------------------------------------------------
- %% -export([]).
- %% ====================================================================!
- %% External functions
- %% ====================================================================!
- %% --------------------------------------------------------------------
- %% Func: start/2
- %% Returns: {ok, Pid} |
- %% {ok, Pid, State} |
- %% {error, Reason}
- %% --------------------------------------------------------------------
- start(_Type, _StartArgs) ->
- case tr_sup:start_link() of
- {ok, Pid} ->
- {ok, Pid};
- Error ->
- {error,Error}
- end.
- %% --------------------------------------------------------------------
- %% Func: stop/1
- %% Returns: any
- %% --------------------------------------------------------------------
- stop(_State) ->
- ok.
3、顶层监督模块 tr_sup.erl
点击(此处)折叠或打开
- -module(tr_sup).
- -behaviour(supervisor).
- -export([start_link/0]).
- -export([
- init/1
- ]).
- -define(SERVER, ?MODULE).
- start_link() ->
- supervisor:start_link({local, ?SERVER}, ?MODULE, []).
- init([]) ->
- Server = {tr_server,
- {tr_server,start_link,[]},
- permanent, 2000, worker, [tr_server]},
- {ok,{
- {one_for_one,0,1},
- [Server]
- }
- }.
4、服务器模块 tr_server.erl
点击(此处)折叠或打开
- %%%-------------------------------------------------------------------
- %%% @author <龙二>
- %%% @copyright (C) 2012,
- %%% @doc RPC over TCP server. This module defines a server process that
- %%% listens for incoming TCP connections and allows the user to
- %%% execute RPC commands via that TCP stream.
- %%% @end
- %%% Created : 2 Jul 2012 by <emacs>
- %%%-------------------------------------------------------------------
- -module(tr_server).
- -include_lib("eunit/include/eunit.hrl"). %% Eunit单元测试
- -behaviour(gen_server).
- %% API
- -export([
- start_link/1,
- start_link/0,
- get_count/0,
- stop/0
- ]).
- %% gen_server callbacks
- -export([init/1,handle_call/3,handle_cast/2,handle_info/2,
- terminate/2,code_change/3]).
- -define(SERVER,?MODULE).
- -define(DEFAULT_PORT,1055).
- -record(state,{port,lsock,request_count = 0}).
- %%%===================================================
- %%% API
- %%%===================================================
- %%----------------------------------------------------
- %% @doc Starts the server.
- %%
- %% @spec start_link(Port::integer()) -> {ok,Pid}
- %% where
- %% Pid = pid()
- %% @end
- %%----------------------------------------------------
- start_link(Port) ->
- gen_server:start_link({local,?SERVER},?MODULE,[Port],[]).
- %% @spec start_link() -> {ok,Pid}
- %% @doc Calls 'start_link(Port)' using the default port
- start_link() ->
- start_link(?DEFAULT_PORT).
- %%----------------------------------------------------
- %% @doc Fetches the number of requests made to this server
- %% @spec get_count() -> {ok,Count}
- %% where
- %% Count = integer()
- %% @end
- %%----------------------------------------------------
- get_count() ->
- gen_server:call(?SERVER,get_count).
- %%----------------------------------------------------
- %% @doc Stops the server
- %% @spec stop() -> ok
- %% @end
- %%----------------------------------------------------
- stop() ->
- gen_server:cast(?SERVER,stop).
- %%%===================================================
- %%% gen_server callbacks
- %%%===================================================
- init([Port]) ->
- {ok,LSock} = gen_tcp:listen(Port,[{active,true}]),
- %% 0 is timeout value
- %% a atom msg 'timeout' will be generate
- %% handle_info/2 will handle this msg immediately when init/1 finished
- {ok,#state{port = Port,lsock = LSock},0}.
- handle_call(get_count,_From,State) ->
- {reply,{ok,State#state.request_count},State}.
- handle_cast(stop,State) ->
- {stop,normal,State}.
- %% handle_info/2: handle tcp,port,timeout msg
- handle_info({tcp,Socket,RawData},State) ->
- do_rpc(Socket,RawData),
- RequestCount = State#state.request_count,
- {noreply,State#state{request_count = RequestCount + 1}};
- handle_info(timeout,#state{lsock = LSock} = State) ->
- {ok,_Sock} = gen_tcp:accept(LSock),
- {noreply,State}.
- terminate(_Reason,_State) ->
- ok.
- code_change(_OldVsn,State,_Extra) ->
- {ok,State}.
- %%%===================================================
- %%% Internal functions
- %%%===================================================
- do_rpc(Socket,RawData) ->
- try
- {M,F,A} = split_out_mfa(RawData),
- Request = apply(M,F,A),
- gen_tcp:send(Socket,io_lib:fwrite("~p~n",[Request]))
- catch
- _Class:Err ->
- gen_tcp:send(Socket,io_lib:fwrite("~p~n",[Err]))
- end.
- split_out_mfa(RawData) ->
- MFA = re:replace(RawData,"\r\n$","",[{return,list}]),
- {match,[M,F,A]} =
- re:run(MFA,
- "(.*):(.*)\s*\\((.*)\s*\\)\s*.\s*$",
- [{capture,[1,2,3],list},ungreedy]),
- {list_to_atom(M),list_to_atom(F),args_to_terms(A)}.
- args_to_terms(RawArgs) ->
- {ok,Toks,_Line} = erl_scan:string("[" ++ RawArgs ++ "]. ",1),
- {ok,Args} = erl_parse:parse_term(Toks),
- Args.
5、启动整个应用的开启模块 tr.erl
点击(此处)折叠或打开
- -module(tr).
- -export([start/0]).
- %%
- %% API Functions
- %%
- %% 启动应用
- start() ->
- case application:start(tcp_rpc) of
- ok ->
- ok;
- Msg ->
- {failur, Msg}
- end.
- %% 关闭应用
- stop() ->
- case application:stop(tcp_rpc) of
- ok ->
- ok;
- Msg ->
- {failure, Msg}
- end.
6、启动脚本 start_tr.sh (windows下为start_tr.bat)
点击(此处)折叠或打开
- erl -pa ebin -name tr@127.0.0.1 -setcookie tr -s tr start
- chmod +x start_tr.sh
- windows下的话,需要将erl这个程序加入到环境变量,否则就要使用绝对路径来应用erl程序
点击(此处)折叠或打开
- { ["src/*"]
- , [
- {outdir, "./ebin"}]
- }.
配合 erl -make 来编译这个应用。
- , [
- {outdir, "./ebin"}]
- }.
配合 erl -make 来编译这个应用。
一个完整的Erlang应用的更多相关文章
- 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车
阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...
- 【如何快速的开发一个完整的iOS直播app】(美颜篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,美颜功能是很重 ...
- 【如何快速的开发一个完整的iOS直播app】(采集篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,首先需要采集主 ...
- 【如何快速的开发一个完整的iOS直播app】(播放篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看上篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,集成ijkpl ...
- 【如何快速的开发一个完整的iOS直播app】(原理篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的 ...
- 一个完整的Http请求
一个完整的http请求,通常有以下7点: 1.建立tcp连接 2.web浏览器web服务器发送请求命令 3.web浏览器发送请求头信息 4.web服务器应答 5.web服务器发送应答信息 6.web服 ...
- Django1.8教程——从零开始搭建一个完整django博客(一)
第一个Django项目将是一个完整的博客网站.它和我们博客园使用的博客别无二致,一样有分类.标签.归档.查询等功能.如果你对Django感兴趣的话,这是一个绝好的机会.该教程将和你一起,从零开始,搭建 ...
- 第三十六课:如何书写一个完整的ajax模块
本课主要教大家如何书写一个完整的ajax模块,讲解的代码主要跟ajax有关,而jQuery的ajax模块添加了Deferred异步编程的机制,因此对ajax的理解难度增大,还是忽略掉.但是我要讲解的代 ...
- 【如何快速的开发一个完整的iOS直播app】(推流篇)
前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,肯定需要流媒体服务器,本篇主要讲解直播中流媒体服务器搭建,并且讲解了如 ...
随机推荐
- Sql Server 2014完全卸载
经历过好多次Sql server的安装与卸载,有时发现自己卸载的费时费力,单纯地卸载个软件就要吐血了,那么现在我觉得是时候整理一下了. 1.在运行中输入services.msc,然后找到所有跟Sql ...
- Eclipse Class Decompiler——Java反编译插件手工配置方法
最近在eclipse上配置了java反编译插件,但是不好用,原因是我的eclipse之前有手动配置过一些类似的java反编译插件,当我将原来的插件完全卸载后重新配置才正常配置上去,自动配置java反编 ...
- COGS——C2274. [HEOI 2016] tree
http://www.cogs.pro/cogs/problem/problem.php?pid=2274 ★☆ 输入文件:heoi2016_tree.in 输出文件:heoi2016_tre ...
- 推荐一个iOS应用UI界面设计站点
Patterns是一个分享ios应用UI界面的站点,专注于分享iOS应用UI界面的细节.依照设计元素进行分类,依照iOS经常使用功能对各类UI进行分类展示. 链接:url=http%3A%2F%2Fw ...
- iOS_02_第一个C语言程序(理解编译、连接、运行)
一.开发工具的选择 1. 可以用来写代码的工具:记事本.ULtraEdit.Vim.Xcode等. 2. 选择XCode的原因:苹果公司官方提供的开发利器.简化开发的工程.有高亮显示功能. 3. 使用 ...
- python3 用递归方法列出所有目录与文件
python3 用递归方法列出所有目录与文件 # !/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan import os ...
- C++ tab键实现自动补全输入功能
一.简介 由于项目中写了个测试的控制台程序,是每次读取一行,即通过getline()来实现的,所以每次必须输入全路径名称,才能实现运行. 大家都觉得麻烦,就写了个tab键自动选择补全的. 目前基本可实 ...
- POJ 1753 Flip Game DFS枚举
看题传送门:http://poj.org/problem?id=1753 DFS枚举的应用. 基本上是参考大神的.... 学习学习.. #include<cstdio> #include& ...
- 【MongoDB】在Mongodb使用shell实现与javascript的动态交互
关于利用mongodb的shell运行脚本,这点在曾经的文章中有点遗漏:如今在此篇博客中做个补充: 一.在命令行中传入脚本文件 定义一个javasciprt文件,名称为:script1.js,内容例如 ...
- swift学习第十二天:类的属性定义
类的属性介绍 Swift中类的属性有多种 存储属性:存储实例的常量和变量 计算属性:通过某种方式计算出来的属性 类属性:与整个类自身相关的属性 存储属性 存储属性是最简单的属性,它作为类实例的一部分, ...