1. 一个 Actor 可以处理多个 WebSocket
2. 客户端终止 WebSocket，服务端可以收到通知
3. 更加容易集群化，并且使用 Actor Router 进行负载平衡

## Introduction

### Theory

1. Source 处理从 Actor 向 Client 发送的消息
2. Sink 处理从 Client 向 Actor 发送的消息

## Implementation 实现

### Sink Source Flow

#### Source.actorRef

Creates a Source that is materialized as an akka.actor.ActorRef.

Messages sent to this actor will be emitted to the stream if there is demand from downstream, otherwise they will be buffered until request for demand is received.

#### mapMaterializedValue

It is important to remember that even after constructing the RunnableGraph by connecting all the source, sink and different operators, no data will flow through it until it is materialized. Materialization is the process of allocating all resources needed to run the computation described by a Graph (in Akka Streams this will often involve starting up Actors).

#### Sink.actorRef

Sends the elements of the stream to the given ActorRef.

#### Flow map and to

def mapT ⇒ T): Repr[T]

Transform this stream by applying the given function to each of the elements as they pass through this processing step.
Emits when the mapping function returns an element
Backpressures when downstream backpressures
Completes when upstream completes
Cancels when downstream cancels

def toMat2: Sink[In, Mat]

Connect this Flow to a Sink, concatenating the processing steps of both.

The materialized value of the combined Sink will be the materialized value of the current flow (ignoring the given Sink’s value), use toMat if a different strategy is needed.

def actorRef[T](ref: ActorRef, onCompleteMessage: Any) 的第二个参数表示：

If the target actor terminates the stream will be canceled. When the stream is completed successfully the given onCompleteMessage will be sent to the destination actor. When the stream is completed with failure a akka.actor.Status.Failure message will be sent to the destination actor.

#### Flow.fromSinkAndSource(sink, source)

def fromSinkAndSourceI, O: Flow[I, O, NotUsed]

Creates a Flow from a Sink and a Source where the Flow’s input will be sent to the Sink and the Flow’s output will come from the Source.
The resulting flow can be visualized as:

The completion of the Sink and Source sides of a Flow constructed using this method are independent. So if the Sink receives a completion signal, the Source side will remain unaware of that. If you are looking to couple the termination signals of the two sides use Flow.fromSinkAndSourceCoupled instead.

### Message Handle Flow

1. Sink：从 Stream 获取 String 类型的数据，传递给总操控者 Actor （chatActerRef）
2. Source：向某个特定的 Actor（ar） 发送消息，消息可以传递给 Stream
3. Stream 被终止或取消时，将会有特殊消息（Protocol.CloseConnection）发送给总操控者 Actor （chatActerRef）
4. 特定的 Actor（ar） 创建的时候，将会有特殊消息（Protocol.OpenConnection）发送给总操控者 Actor （chatActerRef）

def viaT, Mat2: Repr[T]

Transform this Flow by appending the given processing steps.

The materialized value of the combined Flow will be the materialized value of the current flow (ignoring the other Flow’s value), use viaMat if a different strategy is needed.

#### Akka Http WebSocket Message type

def mapAsyncT(f: (Out) ⇒ Future[T]): Repr[T]

Transform this stream by applying the given function to each of the elements as they pass through this processing step. The function returns a Future and the value of that future will be emitted downstream. The number of Futures that shall run in parallel is given as the first argument to mapAsync. These Futures may complete in any order, but the elements that are emitted downstream are in the same order as received from upstream.
If the function f throws an exception or if the Future is completed with failure and the supervision decision is akka.stream.Supervision.Stop the stream will be completed with failure.
If the function f throws an exception or if the Future is completed with failure and the supervision decision is akka.stream.Supervision.Resume or akka.stream.Supervision.Restart the element is dropped and the stream continues.
The function f is always invoked on the elements in the order they arrive.
Emits when the Future returned by the provided function finishes for the next element in sequence
Backpressures when the number of futures reaches the configured parallelism and the downstream backpressures or the first future is not completed

Completes when upstream completes and all futures have been completed and all elements have been emitted

Cancels when downstream cancels

### Akka Http Route with Flow

handleWebSocketMessages 文档