Erlang简单并行server

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应该断开并退出。

时间: 2024-10-11 01:44:14

Erlang简单并行server的相关文章

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

本文先讲解一下Java web server都是怎么工作的.web server也叫HTTP server——顾名思义它是用HTTP协议和客户端交互的.客户端一般就是各种各样的浏览器了.相信所有朋友都清楚这个基本事实,否则你也不会看到这个系列文章了. 基于Java的web server必然用到两个极其重要的类:java.net.Socket和java.net.ServerSocket,然后以HTTP消息进行交互. 1. HTTP协议简介(The Hypertext Transfer Protoc

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

原创文章,转载请注明出处:server非业余研究http://blog.csdn.net/erlib 作者Sunface 为什么我要选择Erlang呢? 一.erlang特别适合中小团队创业: erlang有异常成熟.经过电信级别大规模验证的OTP应用库,仅仅须要非常easy的代码就能建立起异常稳定.容错性强.扩展性强.高并发的server框架,这也是erlang最宝贵的核心价值所在. 二.erlang是天生的并发语言: erlang的并发特性是语言级别的,从开发伊始就採用了CSP并发模式, 以

python,socket网络编程,最简单的server端和client端代码

python网络编程三要素:网络地址,端口号,协议 知识点:conn代表的是客户端的socket对象. 下面的server.py和client.py小程序,实现了最简单的socket通信功能. #server.py import socket sk = socket.socket() address = ('127.0.0.1',8080) sk.bind(address) sk.listen(3) print('waitting......') conn,addr = sk.accept()

CentOS 6.8 安装 Erlang 及 RabbitMQ Server

安装 Erlang 19.3 # 安装依赖包 yum install -y gcc gcc-c++ unixODBC-devel openssl-devel ncurses-devel # 下载 erlang 源码包 cd /usr/local/src wget -c http://erlang.org/download/otp_src_19.3.tar.gz # 解压 tar -xzvf ./otp_src_19.3.tar.gz # 编译安装 cd ./otp_src_19.3 ./conf

写一个最简单的 Server

import java.net.*;import java.io.*;public class Server{ public static void main(String[] args) throws Exception{ ServerSocket serversocket=new ServerSocket(8888); Socket socket=serversocket.accept(); InputStream in=new FileInputStream("C:/Test/test.t

Erlang -奇偶并行排序

-module (exe9). -export ([start/2,handle/4]). % L=[2,12,14,25,31,42,43,43,13,34,34,41,41,312,352,354]. % 将数据分给各个进程,并创建 nodecreater([],Pids,M,Id,Master) -> io:format("Pids:~w Id:~w Master:~w~n",[Pids,Id,Master]), lists:reverse(Pids); nodecreat

简单sql server数据库自动还原脚本

创建脚本文件创建bat文件,在windows中添加定时任务,每天定时执行脚本就行huanyuan.sql:脚本文件db.log :日志文件 原文地址:http://blog.51cto.com/wumingfeixue/2096530

创建一个简单的 MDM server(1)

前提:已获得 APNS 证书 ,已完毕 MDM 配置描写叙述文件的制作.请參考< MDM 证书申请流程 >一文和<配置MDM Provisioning Profile>. 环境:OSX 10.9.2,JDK 1.6.Eclipse JavaEE Helois,Tomcat 7.0 一.前言 <THE IOS MDMPROTOCOL>(即Inside Apple MDM)一文中描写叙述了一个简单 MDM Server Python 实现(server.py). 笔者也曾參

接入Erlang控制台的几种方法

在window中调试的时候我们可以通过启动多个cmd窗口运行Erlang节点,在生产环境中我们需要Erlang服务在Centos服务器上后台运行;这就需要在启动的时候添加启动参数detached来脱离终端:      -detached Starts the Erlang runtime system detached from the system console. Useful for running daemons and backgrounds processes. Implies -n