本文共 4282 字,大约阅读时间需要 14 分钟。
在《》中,实现了一个最简单的Netty Demo。
同《》
绑定8087
package com.ct.netty.http.IIwebsocket;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;/** * @Author LaoHa * @Date 2021/6/8 */public class WsServer { public static void main(String[] args) { EventLoopGroup mainGroup = new NioEventLoopGroup(); EventLoopGroup subGroup = new NioEventLoopGroup(); try { ServerBootstrap server = new ServerBootstrap(); server.group(mainGroup, subGroup) .channel(NioServerSocketChannel.class) //添加自定义初始化处理器 .childHandler(new WsServerInitializer()); ChannelFuture future = server.bind(8087).sync(); future.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); }finally { mainGroup.shutdownGracefully(); subGroup.shutdownGracefully(); } }}
package com.ct.netty.http.IIwebsocket;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;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.stream.ChunkedWriteHandler;/** * @Author LaoHa * @Date 2021/6/8 */public class WsServerInitializer extends ChannelInitializer{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); //websocket基于http协议,所以需要http编解码器 pipeline.addLast(new HttpServerCodec()); //添加对于读写大数据流的支持 pipeline.addLast(new ChunkedWriteHandler()); //对httpMessage进行聚合 pipeline.addLast(new HttpObjectAggregator(1024 * 64)); // ================= 上述是用于支持http协议的 ============== //websocket 服务器处理的协议,用于给指定的客户端进行连接访问的路由地址 //比如处理一些握手动作(ping,pong) pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); //自定义handler pipeline.addLast(new ChatHandler()); }}
package com.ct.netty.http.IIwebsocket;import io.netty.channel.Channel;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.channel.group.ChannelGroup;import io.netty.channel.group.DefaultChannelGroup;import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;import io.netty.util.concurrent.GlobalEventExecutor;import java.time.LocalDateTime;/** * TextWebSocketFrame 用于为websockt处理文本的对象 * * @Author LaoHa * @Date 2021/6/8 */public class ChatHandler extends SimpleChannelInboundHandler{ //用于记录和管理所有客户端的channel private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); @Override protected void messageReceived(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception { //客户端传递过来的消息 String content = msg.text(); System.out.println("接收到了客户端的消息是:" + content); //将客户端发送过来的消息刷到所有的channel中 for (Channel channel : clients) { //channel.writeAndFlush(msg); channel.writeAndFlush( new TextWebSocketFrame("【服务器接收到了客户端的消息】:" + LocalDateTime.now() + ",消息为: " + content)); } } /** * 客户端创建的时候触发,当客户端连接上服务端之后,就可以获取该channel,然后放到channelGroup中进行统一管理 * * @param ctx * @throws Exception */ @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { System.out.println("客户端连接,当前的channel的短ID是:" + ctx.channel().id().asShortText()); clients.add(ctx.channel()); } /** * 客户端销毁的时候触发 * * @param ctx * @throws Exception */ @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { //当handlerRemoved 被触发时候,channelGroup会自动移除对应的channel //clients.remove(ctx.channel()); System.out.println("客户端断开,当前被移除的channel的短ID是:" + ctx.channel().id().asShortText()); }}
运行WsServer,启动一下服务端。
在Idea中,选中index.html,右键-Run,运行客户端。转载地址:http://almdi.baihongyu.com/