netty-websocket server

通过netty构造websocket server端,本质上和构造Tcp服务端一致;

@Component
public class WSServer {
    private final static Logger log = LoggerFactory.getLogger(WSServer.class);

    private static class SingletionWSServer {
        static final WSServer instance = new WSServer();
    }

    public static WSServer getInstance() {
        return SingletionWSServer.instance;
    }

    private EventLoopGroup mainGroup;
    private EventLoopGroup subGroup;
    private ServerBootstrap server;
    private ChannelFuture future;

    public WSServer() {
        mainGroup = new NioEventLoopGroup();
        subGroup = new NioEventLoopGroup();
        server = new ServerBootstrap();
        server.group(mainGroup, subGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new WSServerInitialzer());
    }

    public void start() {
        try {
            this.future = server.bind(8088);
            log.info("netty websocket server start success...");
        } catch (Exception e) {
            log.error("netty websocket server start error..." + e.getMessage());
        }
    }
	// 启动
    public static void main(String[] args) {
        getInstance().start();
    }
}
public class WSServerInitialzer extends ChannelInitializer<SocketChannel> {

	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		// websocket 基于http协议,所以要有http编解码器
		pipeline.addLast(new HttpServerCodec());
		// 对写大数据流的支持 
		pipeline.addLast(new ChunkedWriteHandler());
		pipeline.addLast(new HttpObjectAggregator(1024*64));
		// 如果是读空闲或者写空闲,不处理
		pipeline.addLast(new IdleStateHandler(8, 10, 12));
		// 路由 ws 为客户端访问路径
		pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
		// 自定义的handler
		pipeline.addLast(new WsHandler());
	}

}
public class WsHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

	// 用于记录和管理所有客户端的channle
	public static ChannelGroup channelGroup =
			new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg)
			throws Exception {
		// 获取客户端传输过来的消息
		String content = msg.text();
		System.out.println(content);
	}
	
	/**
	 * 当客户端连接服务端之后(打开连接)
	 * 获取客户端的channle,并且放到ChannelGroup中去进行管理
	 */
	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		channelGroup.add(ctx.channel());
	}

	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		String channelId = ctx.channel().id().asShortText();
		System.out.println("客户端被移除,channelId为:" + channelId);
		// 当触发handlerRemoved,ChannelGroup会自动移除对应客户端的channel
		channelGroup.remove(ctx.channel());
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		cause.printStackTrace();
		// 发生异常之后关闭连接(关闭channel),随后从ChannelGroup中移除
		ctx.channel().close();
		channelGroup.remove(ctx.channel());
	}
}

访问路径
ip:port/ws

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值