我在开发软件时遇到了问题。
我有一个Netty服务器和多个Netty客户端。但是,当我尝试在新线程中启动它们时,它们会在稍微调试消息后停止。客户端运行在Minecraft服务器软件Bukkit上。其他客户端的其他客户端运行在一个独立的Java程序上,它们工作得很好。
这是我的客户端类:
public class NettyClient extends Thread {
public boolean connected;
/**
* Returns true if the client is connected.
*
* @return boolean
*/
String host;
int port;
public Channel channel;
public BlockingQueue<Packet> queue = new LinkedBlockingDeque<>();
public NettyClient(String host, int port) {
this.host = host;
this.port = port;
}
@Override
public void run() {
boolean epoll = Epoll.isAvailable();
System.out.println("[Sys] Server-Typ: " + (epoll ? "Epoll" : "Nio"));
EventLoopGroup mainEventLoopGroup = epoll ? new EpollEventLoopGroup() : new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.group(mainEventLoopGroup)
.channel(epoll ? EpollSocketChannel.class : NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(final SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("encoder", new PacketEncoder());
socketChannel.pipeline().addLast("decoder", new PacketDecoder());
socketChannel.pipeline().addLast("wrapperhandler", new WrapperHandler());
}
});
ChannelFuture f = bootstrap.connect(host, port).channel().closeFuture().syncUninterruptibly();
this.channel = f.channel();
System.out.println("Succesfully established connection to the wrapper server!");
channel.writeAndFlush(new PacketServerLogIn(System.getProperty("servername"),System.getProperty("servergroup"), Bukkit.getServer().getIp(),Bukkit.getOnlinePlayers().size(),Bukkit.getMaxPlayers(),ServerState.WAITING));
RedisBuilder.getInstance().startUpdateScheduler();
} catch (Exception e) {
e.printStackTrace();
} finally {
mainEventLoopGroup.shutdownGracefully();
}
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public Channel getChannel() {
return channel;
}
public boolean isConnected() {
return connected;
}
}
这是我的服务器:
公共类NetworkServer {
String host;
int port;
public NetworkServer(String host, int port) {
this.host = host;
this.port = port;
}
public void run() {
boolean epoll = Epoll.isAvailable();
System.out.println("[Sys] Server-Typ: " + (epoll ? "Epoll" : "Nio"));
EventLoopGroup mainEventLoopGroup = epoll ? new EpollEventLoopGroup(2) : new NioEventLoopGroup(2);
EventLoopGroup workerEventLoopGroup = epoll ? new EpollEventLoopGroup(2) : new NioEventLoopGroup(2);
ServerBootstrap serverBootstrap = new ServerBootstrap();
try {
serverBootstrap.group(mainEventLoopGroup, workerEventLoopGroup)
.channel(epoll ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(final SocketChannel socketChannel) throws Exception {
final SSLContext sslContext = SSLFactory.createAndInitSSLContext("client.jks");
final SSLEngine sslEngine = sslContext.createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setEnabledCipherSuites(sslContext.getSocketFactory().getSupportedCipherSuites());
socketChannel.pipeline().addLast("ssl", new SslHandler(sslEngine));
// socketChannel.pipeline().addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
//socketChannel.pipeline().addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
socketChannel.pipeline().addLast("decoder", new PacketDecoder());
socketChannel.pipeline().addLast("encoder", new PacketEncoder());
socketChannel.pipeline().addLast("wrapperhandler", new WrapperHandler());
}
});
serverBootstrap.bind(port).channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
mainEventLoopGroup.shutdownGracefully();
workerEventLoopGroup.shutdownGracefully();
}
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
}
我认为Bukkit不喜欢多线程,但如果我错了,请纠正我。
My Netty版本是:4.1.2.Final
答案 0 :(得分:0)
您的问题是由于您正在调用.shutdownGracefully();
引起的,这基本上是对Netty线程&amp;他们应该关闭的渠道。
由于您正在开发BUkkit插件,因此您应该只在插件的onDisable()
部分内调用这些方法。
答案 1 :(得分:0)
对于所有也遇到此错误的人:我找到了解决方法。
您需要使用maven来编译正确的Netty版本。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<relocations>
<relocation>
<pattern>io.netty</pattern>
<shadedPattern>io.nettynew</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
这会将正确的netty版本重新着色到最终的jar中,现在您可以连接到另一台netty服务器,而不会出现任何问题。确保已将Netty依赖项添加到maven:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.29.Final</version>