一、有点复杂的方式,自己处理协议升级、握手等信息
1.创建ServerHandler
package cn.edu.tju;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.FullHttpRequest;import io.netty.handler.codec.http.FullHttpResponse;import io.netty.handler.codec.http.websocketx.*;public class MyWebSocketServerHandler extends SimpleChannelInboundHandler
2.创建WebSocket服务器:
package cn.edu.tju;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.codec.*;import io.netty.handler.codec.http.HttpObjectAggregator;import io.netty.handler.codec.http.HttpServerCodec;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.handler.stream.ChunkedWriteHandler;public class WebSocketServer { public static void main(String[] args) { EventLoopGroup bossGroup=new NioEventLoopGroup(); EventLoopGroup workerGroup=new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap=new ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup); serverBootstrap.channel(NioServerSocketChannel.class); serverBootstrap.childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline channelPipeline=socketChannel.pipeline(); channelPipeline.addLast(new HttpServerCodec()); channelPipeline.addLast(new HttpObjectAggregator(65536)); channelPipeline.addLast(new ChunkedWriteHandler()); channelPipeline.addLast(new MyWebSocketServerHandler()); } }); ChannelFuture channelFuture=serverBootstrap.bind(1234).sync(); channelFuture.channel().closeFuture().sync(); }catch (Exception ex){ System.out.println(ex.getMessage()); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}
二、更简便的方式,使用WebSocketServerProtocolHandler:
1.创建ServerHandler
package cn.edu.tju;import io.netty.channel.Channel;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.websocketx.TextWebSocketframe;import java.time.LocalDateTime;public class MyWebSocketServerHandler2 extends SimpleChannelInboundHandler { @Override protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketframe msg) throws Exception { Channel channel = ctx.channel(); System.out.println(channel.remoteAddress() + ": " + msg.text()); ctx.channel().writeAndFlush(new TextWebSocketframe("来自服务端: " + LocalDateTime.now())); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { System.out.println("ChannelId:" + ctx.channel().id().asLongText()); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { System.out.println("用户下线: " + ctx.channel().id().asLongText()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.channel().close(); }}
2.创建WebSocket服务器:
package cn.edu.tju;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.codec.*;import io.netty.handler.codec.http.HttpObjectAggregator;import io.netty.handler.codec.http.HttpServerCodec;import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.handler.logging.LogLevel;import io.netty.handler.logging.LoggingHandler;import io.netty.handler.stream.ChunkedWriteHandler;public class WebSocketServer2 { public static void main(String[] args) { EventLoopGroup bossGroup=new NioEventLoopGroup(); EventLoopGroup workerGroup=new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap=new ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup); serverBootstrap.channel(NioServerSocketChannel.class); serverBootstrap.handler(new LoggingHandler(LogLevel.INFO)); serverBootstrap.childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline channelPipeline=socketChannel.pipeline(); channelPipeline.addLast(new HttpServerCodec()); channelPipeline.addLast(new ChunkedWriteHandler()); channelPipeline.addLast(new HttpObjectAggregator(8192)); channelPipeline.addLast(new WebSocketServerProtocolHandler("/websocket")); channelPipeline.addLast(new MyWebSocketServerHandler2()); } }); ChannelFuture channelFuture=serverBootstrap.bind(1234).sync(); channelFuture.channel().closeFuture().sync(); }catch (Exception ex){ System.out.println(ex.getMessage()); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}
三、连接WebSocket的html
WebSocket Demo