Erlang简单并行server
(金庆的专栏)
Erlang并行服务器为每一个Tcp连接创建相应的连接进程,处理client数据。
參考 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简单并行server的更多相关文章
- Erlang简单并行服务器
Erlang简单并行服务器(金庆的专栏)Erlang并行服务器为每个Tcp连接创建对应的连接进程,处理客户端数据.参考 Erlang程序设计(第2版)17.1.3 顺序和并行服务器并行服务器的诀窍是: ...
- Ubuntu下erlang连接SQL SERVER 2008
erlang连接SQL Server使用ODBC方法,但在网络上还是缺少资料,自己折腾了2天才成功.现在特记录下来,以供大家借鉴. 基本思路是 erlang odbcserver + unixodbc ...
- 为什么我要选择erlang+go进行server架构(2)
原创文章,转载请注明出处:server非业余研究http://blog.csdn.net/erlib 作者Sunface 为什么我要选择Erlang呢? 一.erlang特别适合中小团队创业: erl ...
- spring cloud 创建一个简单Eureka Server
在Spring Cloud实现一个Eureka Server是一件非常简单的事情.下面我们来写一个Eureka Server DEMO. 编码 父项目pom.xml <?xml version= ...
- 使用HANA Web-based Development Workbench创建最简单的Server Side JavaScript
服务器端的JavaScript, 看下wikipedia的介绍: https://en.wikipedia.org/wiki/JavaScript#Server-side_JavaScript Ser ...
- Tomcat是怎么工作的(2) -- 动手实现山寨版的简单Web Server
本文先讲解一下Java web server都是怎么工作的.web server也叫HTTP server——顾名思义它是用HTTP协议和客户端交互的.客户端一般就是各种各样的浏览器了.相信所有朋友都 ...
- Slickflow.NET 开源工作流引擎快速入门之二: 简单并行分支流程代码编写示例
前言:对于急切想了解引擎功能的开发人员,在下载版本后,就想尝试编写代码,完成一个流程的开发和测试.本文试图从一个最简单的并行分支流程来示例说明,如何快速了解引擎代码的编写. 版本:.NET Core2 ...
- 写一个最简单的 Server
import java.net.*;import java.io.*;public class Server{ public static void main(String[] args) throw ...
- asp.net Socket的简单Web Server
1.首先初始化socket,包含对端点以及对连接队列长度的初始化 IPAddress address = IPAddress.Loopback; IPEndPoint endPoint = ); So ...
随机推荐
- CodeWars for JavaScript
SubClass https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes Sub classing with ...
- mysql InnoDB引擎 共享表空间和独立表空间(转载)
PS:innodb这种引擎,与MYISAM引擎的区别很大.特别是它的数据存储格式等.对于innodb的数据结构,首先要解决两个概念性的问题: 共享表空间以及独占表空间. 1.什么是共享表空间和独占表空 ...
- Ubuntu: Firefox is already running, but is not responding
关于Ubuntu: Firefox is already running, but is not responding问题的解决办法 最近firefox总是开不开,出现“Firefox is alre ...
- BZOJ 3524主席树裸题 (雾)
思路: 按权值建一棵主席树 (但是这好像不是正解 空间复杂度是不对的--.) //By SiriusRen #include <cstdio> #include <cstring&g ...
- POJ 3667 线段树+标记
自从某次考试写线段树写挂了以后 这是第一次写线段树,,,,,, 这是一个伤心的故事-- 题意: 思路: 标记 维护从左到右的最大值 从右到左的最大值 区间内的最大值-- 然后就一搞 就出来了 //By ...
- SQL 循环30日
循环30日的统计 大概格式是 with Date as ( select cast(DATEADD(mm, DATEDIFF(mm,,getdate()), ) as datetime) Date u ...
- Oracle的Clob转换类型
import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; imp ...
- JTable表格案例
package com.szht.gpy.frame; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import ...
- WLAN HAL
WLAN HAL WLAN 框架具有三个 WLAN HAL 表面,分别由三个不同的 HIDL 软件包表示: 供应商 HAL:Android 专用命令的 HAL 表面.HIDL 文件位于 hardw ...
- decision tree 决策树(一)
一 决策树 原理:分类决策树模型是一种描述对实例进行分类的树形结构.决策树由结点(node)和有向边(directed edge)组成.结点有两种类型:内部结点(internal node)和叶结点( ...