Open abhipsaMisra opened 3 years ago
In order for a downstream library to not send multiple TCP packets for the same PUBLISH packet, there are three options that I can think of:
ChannelOutboundBuffer.TotalPendingWriteBytes
property to ((IByteBuffer)ChannelOutboundBuffer.Current).GetIoBuffer().Count
and use that to validate if this is the terminal byte buffer being sent for the current packet.
ClientWebSocket.SendAsync()
with endOfMessage
marked as true.ClientWebSocket.SendAsync()
with endOfMessage
marked as false.@nayato Do you think option 2 is a logical solution for this issue? Can we rely on ChannelOutboundBuffer.TotalPendingWriteBytes
to infer if the current message is the terminal message for the current packet?
Going with option 2 you're still going to have multiple WS data frames on the wire. It's just that not every one of them will be marked with FIN flag. That said current behavior is compliant with MQTT over WS spec ([MQTT-6.0.0-2]).
I assume the ask is to not split messages in the first place where possible. I'd suggest to modify DoWrite
implementation to consolidate buffers accumulated in channelOutboundBuffer
before calling SendAsync
.
On option 1: The issue at hand is specific to channel implementation for integration with WebSocket in SDK. Writing out messages in a single buffer would result in an additional copy of message payload - a high cost operation.
The Mqtt encoder splits the PUBLISH packet into different frames, one containing the topic and QoS information, the other containing an optional payload data.
This causes the downstream socket implementation to send them as different different packets. Since the netty implementation encodes the entire PUBLISH packet into the same byte buffer, is there a particular reason dotnetty chose to implement it this way?
Related issue: https://github.com/Azure/azure-iot-sdk-csharp/issues/1814