1,Client-Server原则 (转)
client-server模型由一个中心服务器和任意多的客户端组成
该模型主要用来做资源管理操作,不同的客户端共享一个通用的资源,服务器负责管理该资源
2,例子
- -module(ch3).
- -behaviour(gen_server).
-
-
-export([start_link/0]).
-
-export([alloc/0, free/1]).
-
-export([init/1, handle_call/3, handle_cast/2]).
-
- start_link() ->
- gen_server:start_link({local, ch3}, ch3, [], []).
-
- alloc() ->
- gen_server:call(ch3, alloc).
-
- free(Ch) ->
- gen_server:cast(ch3, {free, Ch}).
-
- init(_Args) ->
- {ok, channels()}.
-
- handle_call(alloc, _From, Chs) ->
- {Ch, Chs2} = alloc(Chs),
- {reply, Ch, Chs2}.
-
- handle_cast({free, Ch}, Chs) ->
- Chs2 = free(Ch, Chs),
- {noreply, Chs2}.
-module(ch3).
-behaviour(gen_server).
-export([start_link/0]).
-export([alloc/0, free/1]).
-export([init/1, handle_call/3, handle_cast/2]).
start_link() ->
gen_server:start_link({local, ch3}, ch3, [], []).
alloc() ->
gen_server:call(ch3, alloc).
free(Ch) ->
gen_server:cast(ch3, {free, Ch}).
init(_Args) ->
{ok, channels()}.
handle_call(alloc, _From, Chs) ->
{Ch, Chs2} = alloc(Chs),
{reply, Ch, Chs2}.
handle_cast({free, Ch}, Chs) ->
Chs2 = free(Ch, Chs),
{noreply, Chs2}.
3,启动Gen_Server
ch3:start_link():
- start_link() ->
- gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}
start_link() ->
gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}
gen_server:start_link/4启动一个新进程并连接它,新进程为一个gen_server
1)第一个参数指定gen_server名字,{local, ch3}表示在本地注册一个gen_server进程为ch3
2)第二个参数指定callback module为ch3,在这里接口方法和callback方法都放在一个module里,这是一个好的编程实践
3)第三个参数指定init方法的参数
4)第四个参数为options
如果名字注册成功,新的gen_server进程调用callback方法ch3:init([]),返回{ok, State}
gen_server:start_link是同步的,直到gen_server初始化并且可以接收请求才返回,gen_server:start_link由supervisor启动,它是supervision tree的一部分
gen_server:start启动一个单独的进程,gen_server:start不是supervision tree的一部分,它没有supervisor
4,同步请求——Call
同步请求alloc()由gen_server:call/2实现:
- alloc() ->
- gen_server:call(ch3, alloc).
alloc() ->
gen_server:call(ch3, alloc).
ch3是gen_server的名字,alloc是实际的请求
该请求会发送一条消息给gen_server,请求接受以后,gen_server调用handle_call(Request, From, State)并返回{replay, Replay, State1}
5,异步请求——Cast
异步请求free(Ch)由gen_server:cast/2实现
- free(Ch) ->
- gen_server:cast(ch3, {free, Ch}).
free(Ch) ->
gen_server:cast(ch3, {free, Ch}).
ch3是gen_server的名字,{free, Ch}是真正的请求
callback方法为handle_cast(Request, State),返回{noreply, State1}.
6,关闭
6.1 在Supervision Tree中
如果gen_server是supervision tree的一部分,则不需要stop方法。gen_server会被supervisor自动关掉。
如果需要在关闭gen_server之前做清理工作,那么shutdown strategy必须为一个timeout并且必须在gen_server的init方法中设置捕获exit信号
gen_server将在关闭时调用callback方法terminate(shutdown, State):
- init(Args) ->
- ...,
-
process_flag(trap_exit, true),
- ...,
- {ok, State}.
- ...
- terminate(shutdown, State) ->
-
..code for cleaning up here..
- ok.
init(Args) ->
...,
process_flag(trap_exit, true),
...,
{ok, State}.
...
terminate(shutdown, State) ->
..code for cleaning up here..
ok.
6.2 单独的Gen_Servers
如果gen_server不是supervision tree的一部分,那么定义一个stop方法会比较有用:
- ...
-
export([stop/0]).
- ...
- stop() ->
- gen_server:cast(ch3, stop).
- ...
-
- handle_cast(stop, State) ->
- {stop, normal, State};
- handle_cast({free, Ch}, State) ->
- ...
- ...
-
- terminate(normal, State) ->
- ok.
...
export([stop/0]).
...
stop() ->
gen_server:cast(ch3, stop).
...
handle_cast(stop, State) ->
{stop, normal, State};
handle_cast({free, Ch}, State) ->
...
...
terminate(normal, State) ->
ok.
callback方法处理stop请求,然后返回{stop, normal, State1},norma指定这是一个正常的关闭,State1为gen_server的state的新的值
这将使得gen_server调用terminate(normal, State1),然后优雅的关闭服务器
7,处理其他消息
如果gen_server可以接受除了请求外的其他消息,那么callback方法handle_info(Info, State)必须实现来处理它们
例如gen_server连接到supervisor以为的其他进程并捕获到exit信号,这时就会接受一个exit消息
- handle_info({'EXIT', Pid, Reason}, State) ->
- ..code to handle exits here..
- {noreply, State1}.
handle_info({'EXIT', Pid, Reason}, State) ->
..code to handle exits here..
{noreply, State1}.
补充:gen_server exports and callbacks
- gen_server module callback module
-
gen_server:start_link -------> Module:init/1
- gen_server:start
-
gen_server:call -------------> Module:handle_call/3
- gen_server:multi_call
-
gen_server:cast -------------> Module:handle_cast/2
- gen_server:abcast
- gen_server:replay
- gen_server:enter_loop
-
Module:handle_info/2
-
Module:terminate/2
-
Module:code_change/3
分享到:
相关推荐
在IT行业中,`gen_server`是Erlang OTP(开放电信平台)框架中的一个核心组件,它提供了一种模式化的方式来实现服务器进程。本篇博客“gen_server tasting 之超简单名称服务(续)”主要探讨了如何使用gen_server来...
在Erlang编程语言中,`gen_server`行为是一个强大的模块,用于构建具有状态的、容错的服务。这篇名为“gen_server tasting 之超简单名称服务”的博客文章可能介绍了如何利用`gen_server`来实现一个简单的命名服务。...
在IT行业中,`gen_server` 是Erlang OTP(开放电信平台)框架中的一个核心行为模块,用于构建可靠且容错的服务。它提供了一种模式,使得开发者可以编写并发、状态管理和故障恢复的服务器进程。在"gen_server tasting...
- 处理连接请求,为每个新连接创建一个新的进程(通常是一个gen_server或gen_fsm行为)。 - 注册和登录逻辑,处理用户认证请求。 - 监听和转发消息,确保消息在正确用户间传递。 - 错误处理和异常恢复,确保系统的...
《Erlang gen_server在OcamlAsync中的实现探索》 Erlang的gen_server是其并发模型的核心组件,它提供了一种强大的状态管理和错误处理机制。而在OCaml语言中,尽管有着自己的并发库如Async,但直接移植或模仿Erlang...
Erlang中的`gen_server`模块是OTP (Open Telecom Platform)设计原则的一部分,它提供了一种标准的方式来实现客户端-服务器架构。gen_server行为模块旨在简化并发处理和错误管理,允许多个客户端共享服务端的资源。它...
通用 TCP 服务器 通用 TCP 服务器( gen_tcp_server ) 是一种 Erlang 行为,提供快速简便的方法将 TCP 服务器功能添加到您的应用程序。 它被实现为管理 TCP 连接的主管,因为它是孩子。如何使用它? 运行make来构建。...
在本文中,我们将深入探讨如何使用Erlang构建一个简易的聊天室,主要涉及的关键技术是gen_tcp和gen_server。Erlang是一种并发性极强、面向进程的编程语言,特别适合于构建高可用性和可扩展性的分布式系统,如聊天室...
通过端口连接在Erlang / Elixir中制作nodejs gen_server的节点库。 该模块使您能够: 在Binary Erlang Term和javascript类型之间进行解码和编码 通过nodeJS可读和可写(双工)创建一个简单的Erlang端口接口 创建一...
接下来我们就要实现我们的终极目标了:system_server(JAVA端)与服务端相互通信; 预处理 首先先解释下一个“玄学”的情况:在前两章的操作完成后,我们不需要添加任何JAVA类,即可直接使用; 究其原因,是因为在我们...
bin/sh: ./gen_test_char: cannot execute binary file ,这个时候我们需要编一个X86版本的gen_test_char来取代他,如果不想编译,可以直接下载,放到httpd-2.2.22/server目录下,继续make,编译成功 最终安装的东西...
2. **启动服务器**:使用gen_server或者其他Erlang OTP行为启动gen_http服务器实例。 3. **发起请求**:通过服务器实例向指定URL发起HTTP请求,可以设置请求头、方法、超时等参数。 4. **处理响应**:gen_http...
首先,gen_bittorrent这个名字来源于Erlang的通用行为模式gen_server,这是一个设计模式,用于实现服务器进程,它提供了一种标准的方式来处理请求和状态管理。gen_bittorrent库将这种模式应用于BitTorrent种子文件的...
- **tcp_server_app模块**: 实现gen_server行为,作为服务器的主进程,处理启动、停止监听器和客户端管理器的请求。 - **tcp_listener模块**: 实现gen_server行为,用于监听TCP连接。它需要注册一个socket,并在接收...
例如,在 `handle_call/3` 中不要直接调用 `gen_server:call/2`,可以考虑使用 `gen_server:cast/2` 来异步处理消息。 ##### 3. gen_fsm详解 - **gen_fsm** 提供了一个框架用于实现有限状态机,适用于处理复杂的...
标题中的“HP ProLiant DL388p Gen8显卡驱动_SERVER2008”指的是一款专为HP ProLiant DL388p Gen8服务器设计的显卡驱动程序,适用于Microsoft Windows Server 2008 R2 64位操作系统。这款驱动程序在描述中被提到已经...
它使用handle_basic_deliver/3和handle_basic_cancel/2的附加回调扩展了gen_server行为。 除此之外,还有几个用于设置连接、交换和队列的包装器。 还包括用于轮询和订阅的工具。 gen_amqp使用作为 AMQP 客户端,但...
bin/sh: ./gen_test_char: cannot execute binary file ,这个时候我们需要编一个X86版本的gen_test_char来取代他,如果不想编译,可以直接下载,放到httpd-2.2.22/server目录下,继续make,编译成功 最终安装的东西...
1. `gen_server`行为:Erlang的`gen_server`行为提供了一种标准方式来实现服务器进程,它包含了一系列的回调函数,如`init/1`(初始化)、`handle_call/3`(处理同步调用)、`handle_cast/2`(处理异步消息)和`...
2. **gen_server**:gen_server是Erlang中的一种行为(behavior),它提供了一种标准的方式来处理服务请求、状态管理和错误处理。在文件存储系统中,gen_server可能包含如下功能:接收上传请求,将文件保存到磁盘,...