These first two problems are the same problem.
ChannelHandlers aren't untyped, they're just not compile-time-type-checked. ChannelHandlers have 4 relevant associated types: InboundIn, InboundOut, OutboundIn, OutboundOut. The first two belong to inbound handlers, the third to outbound handlers, and any channel handler can have the fourth.
ChannelHandlers are linked together in a list, as shown in the diagram you've linked. The head of this list is the network side. On the inbound path, each handler's InboundOut must match the InboundIn of the handler after it (after meaning "closer to the tail". On the outbound path, each handler's OutboundOut must match the OutboundIn of the handler before it (before meaning "closer to the head").
These types are required to align, one handler to another, in order. If they do not align, there will be runtime crashes. We have investigated getting this to be compile-time type checked, and this is still a thing we want to do, but we're trying to balance this with the freedom to rearrange the pipeline at runtime.
The three-layer formation doesn't apply to ChannelHandlers: they aren't layered. It applies to Channels. In general, a ChannelHandler is in one-and-only-one Channel, and so the layering is completely invisible to it.
To your "what": NIO's ChannelPipeline can send any kind of structured data. In our case, that allows us to build a useful abstraction on top of the listening socket by sending channels down the pipeline.
Forward them.
We know this sucks. We've known for years. We want to fix it.
The following rough algorithm works:
- Decide if you need to transform reads, writes, or both.
- Depending on the answer to the above, conform to
ChannelInboundHandler (reads), ChannelOutboundHandler (writes), or ChannelDuplexHandler (both).
- Provide the required associated types that the conformance asks for. This means deciding about your Inbound/Outbound- in and out types.
- Write your logic.
NIO itself does have a wide range of examples that you might crib from. For example, WebSocketFrameEncoder.
Yes, though there isn't only one way they're required to work.