EchoServer

上篇文章里,我们用Akka写了一个简单的HelloWorld样例,对Akka(以及Actor模式)有了初步的认识。本文将用Akka写一个EchoServer,看看在Actor的世界里,怎样使用TCP协议

Github项目

照例。EchoServer的代码被放在了Github上。EchoServer比HelloWorld略微复杂一点,一共同拥有三个类。例如以下图所看到的:

Main

这次先从主类入手:

main()方法的第一行创建了一个Actor系统,名字为mySystem。接下来的四行代码。请看以下的详解。

TCP Manager

Akka将整个TCP层抽象为一个Actor,这个Actor就是TCP Manager。在main()方法的第二行代码里,我们给Actor系统加入了一个TCP Manager,并和它的经纪人取得了联系:

ActorRef tcpManager = Tcp.get(mySystem).getManager();

如今我们的Actor系统看起来是这样:

Props

Props应该是Properties的缩写,它的作用是告诉Actor系统怎样创建一个Actor。Props提供了四个工厂方法来创建Props实例,例如以下所看到的:

public static Props create(Class<?

> type, Object[] os)
public static <T extends Actor> Props create(Class<T> type, Creator<T> crtr)
public static <T extends Actor> Props create(Creator<T> crtr)
public static Props create(Class<? > type, Seq<Object> seq)

main()方法的第三行使用了上面的第一个工厂方法。这个工厂方法有两个參数:一个Class。和一个数组(实际上是vararg)。

第一个參数表示Actor的class,第二个參数是传递给Actor构造函数的參数。这样,Actor系统就知道怎样依据Props创建(用反射调用构造函数)一个Actor实例。main()方法的第四行创建了一个Accepter,起名为accepter。Accepter须要用到tcpManager,这也是我们将tcpManager当做第二个參数传递给Props.create()方法的缘故。如今Actor系统变成了以下这样(我用虚线箭头来表示Actor之间的依赖关系):

main()方法的第五行给accepter发了一个消息:整数12345。告诉它绑定port12345,開始监听TCP连接,准备echo服务。

Accepter

Accepter负责监听port,然后把收到的tcp连接交给Handler去处理。Accepter略微有点复杂,以下是所有代码:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenhob28=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

构造函数是为了建立对tcpManager的依赖,以下具体介绍onReceive()方法:

  • 假设收到的消息是Integer类型(port)。我们给tcpManager发送绑定消息,通知它绑定某个port。
  • 假设tcpManager成功绑定port。它会回应已绑定消息(Bound)。
  • 否则,回应绑定失败消息(CommandFailed)。accepter通过调用getContext().stop()方法结束自己。

  • 成功绑定port后。假设有连接到达,则会收到Connected消息。

    accepter通过调用getContext().actorOf()创建一个Handler,然后把它注冊给tcpManager。

    之后tcpManager就会把与这个连接相关的消息发给handler,换句话说,这个连接被handler接管。

Actor之间的父子关系

在Actor系统内部。Actor们之间并非仅仅有简单的依赖(或引用)关系,而是能够形成父子关系:Actor能够创建子Actor。然后把子任务分配给它们去处理。

一个Actor的Children是通过它的context来管理的,上面代码中。accepter通过getContext()来获得它自己的context,然后通过调用context的actorOf()方法创建子Actor。如果如今有两个client连接到了我们的echoserver,那么整个Actor系统将是以下这样(Actor系统内的实线箭头表示父子关系):

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenhob28=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

Handler

最后一个类是Handler,它比較简单,代码例如以下所看到的:

Handler仅仅处理两种消息:

  • Received消息告诉handler有消息到达,由于是echoserver。所以并不关心到达的消息里面是什么内容。getSender()方法能够得到消息的发送者。也就是tcpManager。然后给tcpManager发一条Write消息。告诉它把数据原封不动的写回给client。
  • ConnectionClosed告诉handler连接已经断开,handler通过调用context的stop()方法结束自己短暂的生命。

測试EchoServer

启动EchoServer。然后能够通过telnet命令进行測试,这里就不具体说明了。

结论

要想用Akka写一个echoserver。还是挺难的,须要了解Akka的非常多方面。可是相对于Socket,或者NIO来说,Akka版的echoserver显然更简单。

Akka边学边写(2)-- Echo Server的更多相关文章

  1. Akka边学边写(4)-- MiniRPG

    前面几篇文章用Akka写了HelloWorld和EchoServer,为了更进一步学习Akka,本文将会实现一个非常小的RPG游戏server:MiniRPG. 游戏逻辑 由于是迷你RPG,所以逻辑非 ...

  2. Akka边学边写(1)-- Hello, World!

    Akka Akka是什么呢?直接引用Akka站点上面的描写叙述吧: Akka is a toolkit and runtime for building highly concurrent, dist ...

  3. Akka边学边写(3)-- ByteString介绍

    Akka的IO层设计能够參考这篇文档,本文简介一下ByteString的设计. Immutable消息 Actor之间是通过消息沟通的.但为了避免同步问题,消息必须是Immutable. 因此.Akk ...

  4. netty写Echo Server & Client完整步骤教程(图文)

    1.创建Maven工程 1.1 父节点的pom.xml代码(root pom文件) 1 <?xml version="1.0" encoding="UTF-8&qu ...

  5. [Python]再学 socket 之非阻塞 Server

    再学 socket 之非阻塞 Server 本文是基于 python2.7 实现,运行于 Mac 系统下 本篇文章是上一篇初探 socket 的续集, 上一篇文章介绍了:如何建立起一个基本的 sock ...

  6. [z]libevent入门教程:Echo Server based on libevent 不指定

    [z]https://www.felix021.com/blog/read.php?2068 花了两天的时间在libevent上,想总结下,就以写简单tutorial的方式吧,貌似没有一篇简单的说明, ...

  7. libevent 入门教程:Echo Server based on libevent(转)

    下面假定已经学习过基本的socket编程(socket, bind, listen, accept, connect, recv, send, close),并且对异步/callback有基本的认识. ...

  8. 网络编程-UDP echo server

    1. UDP简介 UDP 和TCP 的区别包括 1. 面向字节流和面向报文 2. TCP必须要建立连接后才能进行数据交换,但是UDP则并没有连接的建立和释放过程.面向字节流说明,tcp报文段(segm ...

  9. 当标签上写了runat="server" 后,<%%>就会无效

    当标签上写了runat="server" 后,<%%>就会无效 //这是错误的写法 <input type="hidden" runat=&q ...

随机推荐

  1. (转)25个增强iOS应用程序性能的提示和技巧--初级篇

    在开发iOS应用程序时,让程序具有良好的性能是非常关键的.这也是用户所期望的,如果你的程序运行迟钝或缓慢,会招致用户的差评.然而由于iOS设备的局限性,有时候要想获得良好的性能,是很困难的.在开发过程 ...

  2. H Language Blueprint

    H Language Blueprint I will design the H language in the very-soon future, it will be like: 1- a scr ...

  3. 某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法

    在某APK中,通过如下方法动态注册了一个BroadcastReceiver,代码参考如下: @Override protected void onAttachedToWindow() { super. ...

  4. UIImageView圆角,自适应图片宽高比例,图片拉伸,缩放比例和图片缩微图

    /*      设置圆角,通过layer中的cornerRadius和masksToBounds即可.            自适应图片宽高比例.通过UIViewContentModeScaleAsp ...

  5. MSN在Win7下80072f0d错误解决

    近期电脑(笔记本联想 K41A)显卡出了点问题(该显卡一周前刚换的新的,竟然不到一周又出问题了,联想的质量真的...),在xp下电脑根本进不了操作系统,不断重新启动(可能驱动.系统垃圾太多有关),于是 ...

  6. WEB服务器6--IIS架构补充篇

    第一部分我将谈谈IIS的两个不同的版本—IIS 5.x 和 IIS 6的处理模型:IIS如何监听来自外界的Http request,如何根据ISAPI Extension Mapping将对于不同Re ...

  7. sql service重置自动增长字段数字的方法

    1.--SQL表重置自增长字段(不删除表的数据) DBCC CHECKIDENT('表名', RESEED, 起始数) 2.--删除表数据的同时,重置自动增长字段 truncate table 表名

  8. 《JavaScript 闯关记》之基本包装类型

    为了便于操作基本类型值,JavaScript 还提供了3个特殊的引用类型:Boolean.Number 和 String.实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象 ...

  9. HTML - EMail链接

    HTML - EMail链接 HTML Email 标签 在标签中,提供一个email地址,你就可以让用户发送邮件,格式是: <a href= "mailto:jack@kingyar ...

  10. linux基础内容学习一:linux下的分区及安装

    linux看系统版本信息 uname -a 如果显示为i386,i686则为32位系统,如果为x86_64则为64位 一块硬盘最多可以有四个主分区其中一个主分区可以用一个扩展分区替换,在这个扩展分区中 ...