Some of the code is a little surprising and required further analysis
The first example (simplified to the core functionality) is
The surprising part is
What purpose is served by
The code fails to compile if it is omitted, but that does not explain the semantics.
The client now receives output hello
conn.flow has type
Flow[ByteString, ByteString, Unit], matching
our expectation that allows us to both read and write bytes.
receiveSink has type
Sink[ByteString,Unit], indicating it consumes bytes.
Those bytes move out through
conn.flow to the client.
Source.empty is then simply a placeholder with which to complete
allow the flow to receive data from the client.