【netty】主动关闭netty server

设计一个可以控制监听端口的http服务端的开启和关闭的功能,启动部分比较简单,关闭查了一下,找到了功能,以下是demo

import com.wangjx.swallow.common.server.IServer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;

@Slf4j
public class HttpServer implements IServer {
    EventLoopGroup boss = null;
    EventLoopGroup work = null;
    ServerBootstrap bootstrap = null;
    Channel channel = null;
    public ChannelHandler channelHandler;
    int port ;

    public HttpServer(int port, ChannelHandler channelHandler){
        this.port = port;
        this.channelHandler = channelHandler;
    }

    @Override
    public int getPort() {
        return this.port;
    }

    public void start() {
        try {
            bootstrap = new ServerBootstrap();
            boss = new NioEventLoopGroup();
            work = new NioEventLoopGroup();
            bootstrap.group(boss, work)
                    .handler(new LoggingHandler(LogLevel.DEBUG))
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new HttpServerInitializer(channelHandler));

            ChannelFuture f = bootstrap.bind(new InetSocketAddress(port)).sync();
            System.out.println("http server start up on port: " + port);
            channel = f.channel();
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("start netty http server exception", e);
        } finally {
            work.shutdownGracefully();
            boss.shutdownGracefully();
        }
    }

    public void stop() {
        try {
            if (channel != null) {
                log.info("http server is stopping listen port {} ...", port);
                channel.close();
                channel = null;
                log.info("http server is stopped to listen port {} !", port);
            }
        } catch (Exception e) {
            log.error("close netty http server exception", e);
        }
    }

    @Override
    public void run() {
        start();
    }
}

start()方法就是启动server的方法,stop()方法就是停止server的方法,stop()方法中可以看到,就是将启动过程中获取到的channel关闭就好。

### Netty TCP Server 实现心跳包机制 在 Netty 的 TCP Server 中实现心跳包机制可以通过 `IdleStateHandler` 来完成。此工具可以监控通道的状态,当某个连接处于空闲状态超过指定时间时触发事件通知[^3]。 以下是基于 Netty 的 TCP Server 和 Client 心跳包机制的完整示例: #### 服务端代码 ```java import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.timeout.IdleStateEvent; import io.netty.handler.timeout.IdleStateHandler; public class HeartbeatServer { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); // 设置读写空闲时间为10秒 p.addLast(new IdleStateHandler(0, 0, 10)); p.addLast(new HeartbeatServerHandler()); } }); ChannelFuture f = b.bind(8080).sync(); // 绑定到端口8080 System.out.println("服务器已启动..."); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } static class HeartbeatServerHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { if ("heartbeat".equals(msg)) { // 接收心跳消息 System.out.println("接收到客户端的心跳:" + msg); ctx.writeAndFlush("ack"); // 返回确认响应 } else { System.out.println("接收到来自客户端的消息:" + msg); } } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { // 如果发生空闲事件 System.out.println("未接收到客户端的心跳,关闭连接"); ctx.close(); // 关闭连接 } } } } ``` #### 客户端代码 ```java import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.timeout.IdleStateHandler; public class HeartbeatClient { public static void main(String[] args) throws Exception { EventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); // 设置写空闲时间为5秒 pipeline.addLast(new IdleStateHandler(0, 0, 5)); pipeline.addLast(new HeartbeatClientHandler()); } }); ChannelFuture future = bootstrap.connect("localhost", 8080).sync(); future.channel().closeFuture().sync(); } static class HeartbeatClientHandler extends SimpleChannelInboundHandler<String> { private int heartbeatCount = 0; @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); sendHeartbeat(ctx); // 连接建立后立即发送心跳 } @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { if ("ack".equals(msg)) { // 收到服务器返回的确认消息 System.out.println("接收到服务器的心跳确认:" + msg); } } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { // 发生空闲事件时重新发送心跳 sendHeartbeat(ctx); } } private void sendHeartbeat(ChannelHandlerContext ctx) { ctx.writeAndFlush("heartbeat"); // 向服务器发送心跳消息 System.out.println("发送第 " + (++heartbeatCount) + " 次心跳"); } } } ``` 上述代码展示了如何利用 Netty 的 `IdleStateHandler` 实现心跳机制。服务端会在一定时间内未接收到任何数据(包括心跳)时主动断开连接[^4]。而客户端会定期向服务端发送心跳包以维持连接活动状态。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值