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>,今天晚上看了看,确实不错,第一眼就 ...
随机推荐
- rmdir&rm
rmdir删除空目录,非文件 rmdir [选项] 目录名 rmdir -p 路径 删除路径里子文件夹后父文件夹若为空也一并删除 rmdir -v 目录名 显示删除信息 rm删除文件,非目 ...
- python打造一个Mysql数字类型注入脚本(1)
前言: 总是想写一个sql注入脚本,但是之前的那些都不行. 这次做好了准备,然后嘿嘿嘿. 准备: sql注入的基础知识 熟悉怎么判断 正文: 思路概念图: 这里我没有限制用户输入,不限制的话可能会 @ ...
- Virtual Box下虚拟机复制后ip地址重复
通过桥接模式上网的虚拟机在复制之后,出现三台机器的ip地址都是一样的,还都可以上网, 主要是因为在复制的时候,把网卡信息啥的都一起复制了, 为了设置为不同的ip,需要修改复制后的机器的mac地址. 首 ...
- empty()和size()的优劣
通常下面代码: if(c.size() == 0) if(c.empty()) 我们会觉得它们是是等价的. 为何empty()比较好? 主要是他们之间的效率有一定差距: empty对任意的容器都是常数 ...
- ●BZOJ 1934 [Shoi2007]Vote 善意的投票
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1934 题解: 题目有点迷. S向为1的点连边,为0的点向T连边,在有关系的两个点之间连双向边 ...
- [BZOJ]1023 cactus仙人掌图(SHOI2008)
NOIP后的第一次更新嗯. Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在 ...
- bzoj1858[Scoi2010]序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 3079 Solved: 1475[Submit][Statu ...
- 笔记13 AOP中After和AfterReturning的区别
AOP中 @Before @After @AfterThrowing@AfterReturning的执行顺序 public Object invoke(Object proxy, Method met ...
- Spring常用接口和类
一.ApplicationContextAware接口 当一个类需要获取ApplicationContext实例时,可以让该类实现ApplicationContextAware接口.代码展示如下: p ...
- JSON.parse()在火狐中的BUG
//用sessionStorage解决load页面刷新问题 { //sessionStorage.removeItem("loadInfo"); var loadInfo=de ...