【问题标题】:Java(Bukkit) Netty Client stops working when started in second threadJava(Bukkit) Netty Client 在第二个线程中启动时停止工作
【发布时间】:2018-09-16 23:55:45
【问题描述】:

我在开发软件时遇到了问题。

我有一台 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;
}

}

这是我的服务器:

公共类网络服务器{

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 不喜欢多线程,但如果我错了,请纠正我。

我的 Netty 版本是:4.1.2.Final

【问题讨论】:

    标签: java netty bukkit


    【解决方案1】:

    您的问题是因为您正在调用 .shutdownGracefully(); 而引起的,这基本上告诉 Netty 线程和通道它们应该关闭。

    由于您正在开发 BUkkit 插件,因此您应该只在插件的 onDisable() 部分中调用这些方法。

    【讨论】:

      【解决方案2】:

      对于同样遇到此错误的所有人:我找到了解决方案。

      您需要使用 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>
      

      【讨论】:

        猜你喜欢
        • 2021-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多