I want to use MQTT over Websockets. In Netty using Websockets is quite easy:
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("codec-http", new HttpServerCodec());
pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
pipeline.addLast("handler", new WebSocketServerHandler());
I've found MQTT broker (moquette) which is based on Netty.
NettyMQTTHandler handler = new NettyMQTTHandler();
ServerBootstrap b = new ServerBootstrap();
b.group(m_bossGroup, m_workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//pipeline.addFirst("metrics", new BytesMetricsHandler(m_metricsCollector));
pipeline.addFirst("idleStateHandler", new IdleStateHandler(0, 0, Constants.DEFAULT_CONNECT_TIMEOUT));
pipeline.addAfter("idleStateHandler", "idleEventHandler", new MoquetteIdleTimoutHandler());
//pipeline.addLast("logger", new LoggingHandler("Netty", LogLevel.ERROR));
pipeline.addLast("decoder", new MQTTDecoder());
pipeline.addLast("encoder", new MQTTEncoder());
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
pipeline.addLast("handler", handler);
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.option(ChannelOption.SO_REUSEADDR, true)
.childOption(ChannelOption.SO_KEEPALIVE, true);
So in the theory I should be able to send MQTT over Websocket but I have no idea if it possible using Netty? Does any have any clues or ideas how to do that? Should I use MessageToMessageCodec and BinaryWebSocketFrame?
Cheers!
Let me assume your MQTTDecoder
consumes ByteBuf
s and produces some MQTT message objects, and MQTTEncoder
does the opposite, which is usually the case.
Then, the ByteBuf
s your codec works with is not a Web Socket message. They need to become the payloads of the Web Socket frames. I would insert the following handlers into the pipeline:
MessageToMessageDecoder
that transforms a WebSocket text (or binary) frame into a ByteBuf
so that MQTTDecoder
can consume it. The transformation should be very simple - just get the content of the Web Socket frame.MessageToMessageEncoder
that transforms a ByteBuf
into a Web Socket text (or binary) frame so that Netty's WebSocketFrameEncoder
can consume it. The transformation should also be very simple - just wrap the ByteBuf
encoded by MQTTEncoder
with a Web Socket frame object.The resulting pipeline will look like the following:
HttpResponseEncoder
HttpRequestDecoder
HttpObjectAggregator(65536)
WebSocketServerProtocolHandler("/your-websocket-endpoint-path")
WebSocketFrameToByteBufDecoder
extends MessageToMessageDecoder
ByteBufToWebSocketFrameEncoder
extends MessageToMessageEncoder
MQTTEncoder
MQTTDecoder
MessageMetricsHandler
handler
WebSocketServerProtocolHandler
will perform necessary handshaking with your web socket client and insert WebSocketFrameEncoder
and WebSocketFrameDecoder
right before WebSocketFrameToByteBufDecoder
. The resulting pipeline after successful handshake will look like the following:
WebSocketFrameEncoder
WebSocketFrameDecoder
WebSocketFrameToByteBufDecoder
extends MessageToMessageDecoder
ByteBufToWebSocketFrameEncoder
extends MessageToMessageEncoder
MQTTEncoder
MQTTDecoder
MessageMetricsHandler
handler
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With