Erlang简单并行服务器

(金庆的专栏)

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的更多相关文章

  1. Erlang简单并行服务器

    Erlang简单并行服务器(金庆的专栏)Erlang并行服务器为每个Tcp连接创建对应的连接进程,处理客户端数据.参考 Erlang程序设计(第2版)17.1.3 顺序和并行服务器并行服务器的诀窍是: ...

  2. Ubuntu下erlang连接SQL SERVER 2008

    erlang连接SQL Server使用ODBC方法,但在网络上还是缺少资料,自己折腾了2天才成功.现在特记录下来,以供大家借鉴. 基本思路是 erlang odbcserver + unixodbc ...

  3. 为什么我要选择erlang+go进行server架构(2)

    原创文章,转载请注明出处:server非业余研究http://blog.csdn.net/erlib 作者Sunface 为什么我要选择Erlang呢? 一.erlang特别适合中小团队创业: erl ...

  4. spring cloud 创建一个简单Eureka Server

    在Spring Cloud实现一个Eureka Server是一件非常简单的事情.下面我们来写一个Eureka Server DEMO. 编码 父项目pom.xml <?xml version= ...

  5. 使用HANA Web-based Development Workbench创建最简单的Server Side JavaScript

    服务器端的JavaScript, 看下wikipedia的介绍: https://en.wikipedia.org/wiki/JavaScript#Server-side_JavaScript Ser ...

  6. Tomcat是怎么工作的(2) -- 动手实现山寨版的简单Web Server

    本文先讲解一下Java web server都是怎么工作的.web server也叫HTTP server——顾名思义它是用HTTP协议和客户端交互的.客户端一般就是各种各样的浏览器了.相信所有朋友都 ...

  7. Slickflow.NET 开源工作流引擎快速入门之二: 简单并行分支流程代码编写示例

    前言:对于急切想了解引擎功能的开发人员,在下载版本后,就想尝试编写代码,完成一个流程的开发和测试.本文试图从一个最简单的并行分支流程来示例说明,如何快速了解引擎代码的编写. 版本:.NET Core2 ...

  8. 写一个最简单的 Server

    import java.net.*;import java.io.*;public class Server{ public static void main(String[] args) throw ...

  9. asp.net Socket的简单Web Server

    1.首先初始化socket,包含对端点以及对连接队列长度的初始化 IPAddress address = IPAddress.Loopback; IPEndPoint endPoint = ); So ...

随机推荐

  1. delphi网络函数大全

    {=========================================================================功 能: 网络函数库时 间: 2002/10/02版 ...

  2. 51nod-1322: 关于树的函数

    [传送门:51nod-1322] 简要题意: 给出n个点的两棵无根树,编号都是从0到n-1 现在每棵树任意选出一条边割断,设第一棵树选出的边为e1,第二棵树选出的边为e2 很显然割断后两棵树各分成了四 ...

  3. tp5使用oss存储图片

    1.申请Access Key ID和Access Key Secret,以及创建好你的Bucket 2.通过composer安装oss插件 通过cmd,到项目的目录下,输入下面的指令. compose ...

  4. Leaflet学习笔记(一)

    一.简介 Leaflet是一个主要适用于移动端交互地图的领先的开源javascript库.虽然js库只有38KB左右,但是却能满足大部分开发者的所有功能需求. Leaflet拥有着简单,高效和实用的设 ...

  5. HUE搭配基础

    * HUE搭配基础 首先简单说一下Hue框架的来源:HUE=HadoopUser Experience,看这名字就知道怎么回事了吧,没错,直白来说就是Hadoop用户体验,是一个开源的Apache H ...

  6. AD域导入导出命令

    AD域 批量组织机构.用户导入导出 参考网站 https://technet.microsoft.com/zh-cn/library/cc753447(v=ws.11).aspx 导入所有命令 均cm ...

  7. SharePoint 第一个网站

    第一个网站 1.建立一个社区门户网站首先要建一个IIS网站,并且把匿名访问勾选上,这样才能真正的访问网站. 创建网站的时候更改自己想要的端口,以便操作 这里更改网站是否启用匿名访问权限.点击是 然后保 ...

  8. windows server 2012安装.NET3.5安装提示需要指定源路径 安装.net3.5提示安装不成功,提示需要指定源路径。

    安装.net3.5提示安装不成功,提示需要指定源路径.   正确的操作步骤: 1.需要下载windows server 2012操作系统盘.用解压工具解压出来.       2012操作系统下载地址: ...

  9. 八 ROI(region of interest)和泛洪填充

    一.ROI 感兴趣区(Region of Interest,ROIs) 是图像的一部分,它通过在图像上选择或使用诸如设定阈值(thresholding) 或者从其他文件(如矢量> 转换获得等方法 ...

  10. 开源映射平台Mapzen加入了Linux基金会的项目

    2019年1月29日,Linux基金会宣布,开源映射平台Mapzen现在是Linux基金会项目的一部分. Mapzen专注于地图显示的核心组件,如搜索和导航.它为开发人员提供了易于访问的开放软件和数据 ...