我正在尝试创建一个简单的MQTT服务器。现在不需要完全符合标准,因此请耐心等待。 问题是,无论我做什么,服务器都不接受TCP请求。实际上,它打开一个端口并响应TCP SYN,但在握手后立即发送RST,从而关闭连接。
我尝试过的呼叫serverBootstrap.bind(...).sync().channel().closeFuture().sync()
如下:Netty Connection not working
我希望会调用channelRead()
,但事实并非如此。
我对Netty相当陌生,而且似乎在掌握其一些基本概念方面似乎失败了。朝正确方向轻推将不胜感激!
serverBootstrap.bind(config.getHost(), config.getPort())
.addListener((ChannelFuture future) -> {
if (future.isSuccess()) {
LOG.info("Bridge bound to {}", future.channel().localAddress());
}
});
private void initializeServerBootstrap() {
serverBootstrap
.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true)
.childHandler(new ChannelInitializer<ServerSocketChannel>() {
@Override
protected void initChannel(ServerSocketChannel channel) {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast("decoder", new MqttDecoder());
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
BridgeConnection connection = createConnection(channel);
serverConnections.put(channel.remoteAddress(), connection);
pipeline.addLast("bridgeInbound", new BridgeInboundHandler(connection));
}
});
}
public class BridgeInboundHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(BridgeInboundHandler.class);
private BridgeConnection connection;
BridgeInboundHandler(BridgeConnection connection) {
this.connection = connection;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
MqttMessage message = NettyUtils.validateMessage(msg);
LOG.info("Channel to {} has read message: {}", ctx.channel().remoteAddress(), message.toString());
connection.handleMessage(message);
} catch (IOException ex) {
LOG.error("Caught exception while trying to parse message.", ex);
ctx.channel().close().addListener((ChannelFuture future) -> {
LOG.error("Closed channel to {} due to exception.", future.channel().remoteAddress());
});
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
LOG.info("Channel with remote address {} has become active.", ctx.channel().remoteAddress());
connection.connect();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
LOG.info("Channel to {} has become inactive.", ctx.channel().remoteAddress());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
LOG.error("Unexpected channel exception.", cause);
ctx.close().addListener(future -> {
LOG.error("Channel was closed due to exception.");
});
}
}
connection.connect()
本质上是通过传递MQTT CONNECT消息来调用channel.writeAndFlush()
。