1.Erlang 世界观
Erlang的世界观是一切都是进程和进程只能通过交换消息进行互动。这种世界观让我们的设计具备了概念完整性,也更易于理解。
有一位用户向我们的Web服务器请求一个名为 hello.html的网页。Web服务器如下:
web_server(Client) ->
receive
{Client, {get, Page}} ->
case file:read(Page) of
{ok, Bin} ->
Client ! {self(), {data, Bin}};
{error, _} ->
Client ! {self(), error}
end,
web_server(Client)
end.
这段代码只接收和发送Erlang数据类型
正常情况下客户端发送的是复杂程度远超Erlang数据类型的HTTP请求,HTTP请求建立在TCP连接上,请求自身也可能会分段发送。
为了让事情更简单,我们在Erlang服务器和接收HTTP客户端消息的TCP驱动之间插入一个名为中间人的进程。中间人会解析HTTP请求,并把它们转变成Erlang消息。
中间人要做的就是解析传入的HTTP请求,把它们转换成Erlang数据类型,并把传出的Erlang数据类型转换成HTTP响应。
2.多用途服务器
摒弃了各种服务需要不同的消息格式这一概念后,就可以用消息统一化来解决多种问题了。
-module(multi_server).
-export([start/0]).
start() -> spawn(fun() -> multi_server() end).
multi_server() ->
receive
{_Pid, {email, _From, _Subject, _Text} = Email} ->
{ok, S} = file:open("mbox", [write,append]),
io:format(S, "~p.~n", [Email]),
file:close(S);
{_Pid, {im, From, Text}} ->
io:format("Msg (~s): ~s~n",[From, Text]);
{Pid, {get, File}} ->
Pid ! {self(), file:read_file(File)};
Any ->
io:format("multi server got:~p~n",[Any])
end,
multi_server().
1.在第8~11行里,它表现出电子邮件客户端的行为。
电子邮件客户端的关键任务是接收邮件并把它保存到你的计算机里(按惯例是一个名为mbox的文件)。我们接收一个消息,打开名为mbox的文件,把消息写入这个文件,任务完成。
2.在第12~13行里,它表现出即时通讯客户端的行为。
即时通讯客户端的关键任务是接收一个消息并告知用户。通过向控制台写入消息来告知用户。
3.在第14~15行里,它表现出FTP/RCP/HTTP服务器的行为。
FTP服务器、HTTP服务器或其他任何文件服务器的关键任务是把一个文件从服务器传送到客户端。
重点:一切消息都使用Erlang数据类型。
3.有状态的模块
通过使用一种被称为元组模块的机制,可以把状态和模块名封装到一起。可以用这种机制来
隐藏信息和创建适配器模块,后者会对使用接口的程序隐藏接口细节。
调用X:Func(....)时,X不必非得是一个原子,它还可以是元组。如果先写X = {Mod, P1,P2, ..., Pn}然后调用X:Func(A1, A2, ..., An),那么实际调用的是Mod:Func(A1, A2, ...,An, X)。举个例子,{foo,1,2,3}:bar(a,b)这个调用会被转换成foo:bar(a,b,{foo,1,2,3})。
有状态的计数器
-module(counter).
-export([bump/2, read/1]).
bump(N, {counter,K}) -> {counter, N + K}.
read({counter, N}) -> N.
但是好像已经不行了.....
官方文件强烈建议不要使用此功能,好像会极大的影响效率。