引子
准确来说,IO API 不算是 Akka Streams的内容,但它却是 Streaming IO (TCP) 的基础。
IO API 编程的第一步,是获取一个管理对象的引用。比如我们想针对TCP编程,可以这么获取 TCP Manager:
manager 是一个 actor 对象,用于处理底层 I/O资源和操作(诸如channels/selectors,或是workers的初始化),同时对于上层提供基于actor 模型的抽象
IO TCP
IO TCP 编程也是 CS 模型的,好处是不需要写繁琐的 SOCKET 逻辑——当然,如果你乐意,也可以掺合这些 SOCKET 事务,比如:在客户端进行连接时,指定SOCKET的SO_NODELAY
( windows里叫TCP_NODELAY
)选项,以启用 Nagle’s algorithm(Akka里默认是禁用):
在 IO TCP编程中,无论是客户端还是服务端,都是一个actor对象,通过它与manger对象及对端的连接进行消息上的交互:
客户端
客户端流程:
- 连接到服务器,即向 manger 发送
Connect
消息 - 接收消息:
CommandFailed
意味着连接失败;Connected
代表了一个成功的连接 Connected
消息的sender()
就代表了与服务器建立TCP连接的代理对象,它亦是一个 ActorRef,我们可以向它Register(handler)
消息,以指定处理它消息的handler(还是一个ActorRef)- 利用hander,可以向对端的服务器发送消息,即写入
ByteString
到SOCKET以抵达服务器,写入消息,是特定的Tcp.Write
、Tcp.WriteFile
、Tcp.CompoundWrite
消息,分别对应了:写入ByteString
、写入文件以及混合写入多种消息 - 同时,如果在
Tcp.Write
消息中指定了ACK事件参数,那么在发送成功后,handler将会接受到ACK
消息
服务端
服务端流程:
- 绑定到服务器,即向 manger 发送
Bind
消息 - 接收消息:
CommandFailed
代表绑定失败;Bound
代表绑定成功;Connected
代表了一个从客户端发来的连接 Connected
消息的sender()
就代表了与客户端建立TCP连接的代理对象,它亦是一个 ActorRef,我们可以向它Register(handler)
消息,以指定处理它消息的handler……- 利用hander,可以向对端的服务器发送消息,即写入
ByteString
到SOCKET以抵达服务器,写入消息,是特定的Tcp.Write
、Tcp.WriteFile
、Tcp.CompoundWrite
消息,分别对应了:写入ByteString
、写入文件以及混合写入多种消息 - 同时,如果在
Tcp.Write
消息中指定了ACK事件参数,那么在发送成功后,handler将会接受到ACK
消息
除了绑定等前置步骤,代理对象的处理和客户端是一样的……
TCP CS 模型实例
客户端
服务端
运行结果
客户端
服务端
打赏作者
您的支持将激励我继续创作!