//springboot(version2.0.2)整合netty(version4.1.25)搭建的websocket服務(wù)端,握手阻塞,握手成功(handlerAdded調(diào)用)但是未返回握手成功信息給前端,
//前端websocket握手阻塞,連接超時(shí)
@Component
public?class?NettySocket?{
????private?static?class?SingletionSocketServer?{
????????static?final?NettySocket?INSTANCE?=?new?NettySocket();
????}
????public?static?NettySocket?getInstance()?{
????????return?SingletionSocketServer.INSTANCE;
????}
????private?EventLoopGroup?parentGroup;
????private?EventLoopGroup?childGroup;
????private?ServerBootstrap?serverBootstrap;
????private?ChannelFuture?future;
????public?NettySocket()?{
????????parentGroup?=?new?NioEventLoopGroup();
????????childGroup?=?new?NioEventLoopGroup();
????????serverBootstrap?=?new?ServerBootstrap();
????????serverBootstrap.group(parentGroup,?childGroup).channel(NioServerSocketChannel.class).childHandler(new?NettySocketInitializer());
????}
????public?void?start()?{
????????this.future?=?serverBootstrap.bind(8065);
????????System.out.println("netty?WebSocket?start?ok");
????}
}初始化器public?class?NettySocketInitializer?extends?ChannelInitializer<SocketChannel>?{
????@Override
????protected?void?initChannel(SocketChannel?ch)?{
????????ChannelPipeline?channelPipeline?=?ch.pipeline();
????????////////////////http協(xié)議的支持????///////////////
????????//Http編解碼器
????????channelPipeline.addLast(new?HttpServerCodec());
????????//對(duì)寫大數(shù)據(jù)流的支持
????????channelPipeline.addLast(new?ChunkedWriteHandler());
????????//Http對(duì)象聚合器,,參數(shù):消息的最大長(zhǎng)度
????????//幾乎在Netty中的編程都會(huì)使用到這個(gè)handler
????????channelPipeline.addLast(new?HttpObjectAggregator(1024?*?64));
????????////////////////http協(xié)議的支持?END///////////////
????????channelPipeline.addLast(new?WebSocketServerProtocolHandler("/nt-ws"));
????????channelPipeline.addLast(new?ChatHandler());
????}
}消息處理@Slf4j
public?class?ChatHandler?extends?SimpleChannelInboundHandler<TextWebSocketFrame>?{
????/**
?????*?記錄和管理所有客戶端
?????*/
????private?static?ChannelGroup?clients?=?new?DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
????@Override
????protected?void?channelRead0(ChannelHandlerContext?ctx,?TextWebSocketFrame?msg)?throws?Exception?{
????????String?content?=?msg.text();
????????log.info("accept:?{}",?content);
????????for?(Channel?channel?:?clients)?{
????????????channel.writeAndFlush(new?TextWebSocketFrame("服務(wù)器消息["?+?ctx.channel().id().asLongText()?+?"]:?"?+?content));
????????}
//????????????clients.writeAndFlush(new?TextWebSocketFrame("服務(wù)器消息["?+?ctx.channel().id().asLongText()?+?"]:?"?+?content));
????}
????@Override
????public?void?handlerAdded(ChannelHandlerContext?ctx)?throws?Exception?{
????????clients.add(ctx.channel());
????????log.info("客戶端連接??——???channel?id?:?{}",?ctx.channel().id().asLongText());
????????log.info("剩余客戶端:{}",?clients.size());
//????????????ctx.channel().writeAndFlush(new?TextWebSocketFrame("連接成功!當(dāng)前在線人數(shù):"?+?clients.size()));
????}
????@Override
????public?void?handlerRemoved(ChannelHandlerContext?ctx)?throws?Exception?{
????????//觸發(fā)該方法ChannelGroup會(huì)自動(dòng)移除對(duì)應(yīng)客戶端的channel,所以不需要專門移除
//????????????clients.remove(ctx.channel());
????????log.info("客戶端連接斷開??——???channel?id?:?{}",?ctx.channel().id().asLongText());
????????log.info("剩余客戶端:{}",?clients.size());
????}
????@Override
????public?void?exceptionCaught(ChannelHandlerContext?ctx,?Throwable?cause)?throws?Exception?{
????????cause.printStackTrace();
????????//?發(fā)生異常之后關(guān)閉連接(關(guān)閉channel),隨后從ChannelGroup中移除
????????ctx.channel().close();
????????clients.remove(ctx.channel());
????}
}Booter啟動(dòng)類@Component
public?class?NettyBooter?implements?ApplicationListener<ContextRefreshedEvent>?{
????@Override
????public?void?onApplicationEvent(ContextRefreshedEvent?event)?{
????????if?(event.getApplicationContext().getParent()?==?null)?{
????????????try?{
????????????????NettySocket.getInstance().start();
????????????}?catch?(Exception?e)?{
????????????????e.printStackTrace();
????????????}
????????}
????}
}
springboot整合netty搭建的websocket服務(wù)端,握手阻塞
成佛的小兔幾
2018-10-19 14:45:46