Erlang简单并行服务器
Erlang简单并行服务器
(金庆的专栏)
Erlang并行服务器为每个Tcp连接创建对应的连接进程,处理客户端数据。
参考 Erlang程序设计(第2版)
17.1.3 顺序和并行服务器
并行服务器的诀窍是:每当gen_tcp:accept收到一个新连接时就立即分裂一个新进程。
为每个新套接字连接创建一个并行进程。
-module(gs_svr).
-author("jinqing").
-behaviour(gen_server).
%% API
-export([start_link/0]).
init([]) ->
gs_listener:start_parallel(),
{ok, #{}}.
gs_svr(GameServer gen_server)启动Tcp监听,并维护连接,如连接计数,发送广播。
start_parallel()创建监听端口,然后创建连接进程。
start_parallel() ->
Port = server_csv:get_my_port(),
lager:info("Starting game server on port ~p...", [Port]),
{ok, ListenSocket} = gen_tcp:listen(Port,
[binary, {packet, 4},
{packet_size, 256 * 1024}, % limit packet size
{reuseaddr, true},
{nodelay, true},
{backlog, 999999},
{active, once}]),
connection:spawn_connection(ListenSocket).
spawn_connection()创建连接进程。每接受一个连接就再创建一个新的连接进程。
-module(connection).
-author("jinqing").
%% API
-export([spawn_connection/1]).
-export([parallel_connect/1, loop/2]).
-spec spawn_connection(ListenSocket :: gen_tcp:socket()) -> pid().
spawn_connection(ListenSocket) ->
spawn(fun() -> ?MODULE:parallel_connect(ListenSocket) end).
-spec parallel_connect(ListenSocket :: gen_tcp:socket()) -> ok.
parallel_connect(ListenSocket) ->
{ok, Socket} = gen_tcp:accept(ListenSocket),
spawn_connection(ListenSocket),
gs_svr:cast_connection_new(self()),
ConnStat = conn_stat:new(),
erlang:send_after(1000, self(), timer_sec),
try ?MODULE:loop(Socket, ConnStat)
catch
Type:E -> lager:error("loop() ~p:~p. ~p",
[Type, E, erlang:get_stacktrace()])
end,
gs_svr:cast_connection_ended(self()),
ok.
-spec loop(Socket :: gen_tcp:socket(), ConnStat :: conn_stat:conn_stat()) -> any().
loop(Socket, ConnStat) ->
receive
{tcp, Socket, Bin} ->
NewConnStat = rpc_handler:handle_bin(Socket, Bin, ConnStat),
inet:setopts(Socket, [{active, once}]),
NewConnStat2 = cutil_dos_checker:on_data(size(Bin), NewConnStat),
?MODULE:loop(Socket, NewConnStat2#{idle_sec=>0});
{tcp_closed, Socket} ->
save_on_end(ConnStat);
{tcp_error, Socket, Reason} ->
save_on_end(ConnStat);
{gs_to_connection, Msg} ->
NewConnStat = handle_gs_msg(Msg, Socket, ConnStat),
?MODULE:loop(Socket, NewConnStat);
timer_sec ->
case conn_timer:timer_sec(ConnStat) of
{ok, NewConnStat} ->
erlang:send_after(1000, self(), timer_sec),
?MODULE:loop(Socket, NewConnStat);
end;
Other ->
lager:error("Unknown msg: ~p", [Other]),
?MODULE:loop(Socket, ConnStat)
end. % This is tail-recursive.
缺点是连接进程没有加入监控树。gs_svr出错重启时,连接进程connection应该断开并退出。
Erlang简单并行服务器的更多相关文章
- Erlang简单并行server
Erlang简单并行服务器 (金庆的专栏) Erlang并行服务器为每一个Tcp连接创建相应的连接进程,处理client数据. 參考 Erlang程序设计(第2版)17.1.3 顺序和并行服务器 并行 ...
- Erlang cowboy websocket 服务器
Erlang cowboy websocket 服务器 原文见于: http://marcelog.github.io/articles/erlang_websocket_server_cowboy_ ...
- C#中使用Socket实现简单Web服务器
上一篇博客中介绍了怎样使用socket访问web服务器.关键有两个: 熟悉Socket编程: 熟悉HTTP协议. 上一篇主要是通过socket来模拟浏览器向(任何)Web服务器发送(HTTP)请求,重 ...
- 用nodejs搭建一个简单的服务器
使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安 ...
- 初学Node(六)搭建一个简单的服务器
搭建一个简单的服务器 通过下面的代码可以搭建一个简单的服务器: var http = require("http"); http.createServer(function(req ...
- 搭建无限制权限的简单git服务器使用git-daemon脚本
如果想要用ubantu架设无限制权限(即不适用gitosis)的简单git服务器,实现git库下载clone,push等简单的基本功能, 可以直接使用git-daemon脚本(非常不安全,建议项目代码 ...
- 运用socket实现简单的服务器客户端交互
Socket解释: 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意 ...
- Ubuntu 14.04搭建简单git服务器
/****************************************************************************** * Ubuntu 14.04搭建简单gi ...
- tomcat解析之简单web服务器(图)
链接地址:http://gogole.iteye.com/blog/587163 之前有javaeyer推荐了一本书<how tomcat works>,今天晚上看了看,确实不错,第一眼就 ...
随机推荐
- Mac OS X磁盘重新分区后 BootCamp Windows启动项丢失
前言 我有一台Mac,装有OS X和Windows两系统,因Windows和OS X都能读写exFAT分区, 故若在Machintosh HD和Windows HD之间开辟一个exFAT分区,可以作为 ...
- [HNOI2013]比赛
题目描述 沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛.此次联 赛共N支球队参加,比赛规则如下: (1) 每两支球队之间踢一场比赛. (2) 若平局,两支球队各得1分. (3) ...
- HDU 5723 Abandoned country 最小生成树+搜索
Abandoned country Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- Codeforces Round #430 A. Kirill And The Game
Kirill plays a new computer game. He came to the potion store where he can buy any potion. Each poti ...
- bzoj2839: 集合计数 容斥+组合
2839: 集合计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 523 Solved: 287[Submit][Status][Discuss] ...
- Miox带你走进动态路由的世界——51信用卡前端团队
写在前面: 有的时候再做大型项目的时候,确实会被复杂的路由逻辑所烦恼,会经常遇到权限问题,路由跳转回退逻辑问题.这几天在网上看到了51信用卡团队开源了一个Miox,可以有效的解决这些痛点,于是乎我就做 ...
- Enum枚举
Java Enum原理 public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }; 实际上,这个声明定义的类型是一个类,它刚好有四个实例,在此尽量不要 ...
- three.js 3D 动画场景
Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机.光影.材质等各种对象.使用它它能让 WebGL 变得更加简单. 下面用Three.js渲染一个物体360 ...
- jquery easyui datagrid设置行样式 不可删除某行
rowStyler: function (index,row) { if (parseInt(row.ksrs) > 0) { return 'color:red'; } }, onLoadSu ...
- kindeditor配合requirejs使用时,ready失效
KindEditor官方的文档在使用KindEditor时是这样的: KindEditor.ready(function(K)) { K.create('#editor_id'); } 使用了自己提供 ...