Netty-Websocket 根据URL路由,分发机制的实现
最近在做netty整合websocket,发现网上很多项目都是最简单的demo,单例的一个项目。
然而公司的项目需要接受几个不同功能的ws协议消息,因此最好是用URL来区分,让页面上采用不同的链接方式。
网上项目出现地址的方法:
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { // 如果HTTP解码失败,返回HHTP异常 if(!req.decoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST)); return; } // 构造握手响应返回,本机测试 WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory("ws://localhost:8088/websocket", null, false); //注意,这条地址别被误导了,其实这里填写什么都无所谓,WS协议消息的接收不受这里控制 handshaker = wsFactory.newHandshaker(req); if(handshaker == null) { // WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel()); WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { handshaker.handshake(ctx.channel(), req); } }
然后,开始看源码,发现ChannelHandlerContext继承的 AttributeMap
然后继续看,AttributeMap有一个方法,attr(),返回Attribut,参数key。而Attrbute中有set()方法。
好了,那么接下来一切都好办了,直接上关键代码。
下面是netty接收到消息处理,第一步首先是http握手,这个没的说。
/** * 接收客户端发送的消息 channel 通道 Read 读 简而言之就是从通道中读取数据,也就是服务端接收客户端发来的数据。但是这个数据在不进行解码时它是ByteBuf类型的 */ @Override protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { // 传统的HTTP接入 if (msg instanceof FullHttpRequest) { handleHttpRequest(ctx, ((FullHttpRequest) msg)); // WebSocket接入 } else if (msg instanceof WebSocketFrame) { if("anzhuo".equals(ctx.attr(AttributeKey.valueOf("type")).get())){ handlerWebSocketFrame(ctx, (WebSocketFrame) msg); System.out.println(1111); }else{ System.out.println(2323); handlerWebSocketFrame2(ctx, (WebSocketFrame) msg); } } }
然后:
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { // 如果HTTP解码失败,返回HHTP异常 if (!req.getDecoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST)); return; } HttpMethod method=req.getMethod(); String uri=req.getUri(); if(method==HttpMethod.GET&&"/webssss".equals(uri)){ //....处理 重点在这里,对于URL的不同,给ChannelHandlerContext设置一个Attribut ctx.attr(AttributeKey.valueOf("type")).set("anzhuo"); }else if(method==HttpMethod.GET&&"/websocket".equals(uri)){ //...处理 ctx.attr(AttributeKey.valueOf("type")).set("live"); } // 构造握手响应返回,本机测试 WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( "ws://localhost:7397/websocket", null, false); handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel()); } else { handshaker.handshake(ctx.channel(), req); } }
握手成功之后,发送消息时会返回第一段代码,因此判断context的Attribut就可以分发路由了,给不同的handlerWebSocketFrame处理机制
分类:
websocket
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?