文章目录
前言
在之前的博客中,着重说明了如何使用netty
整合websocket
实现通信功能。
但在实际的项目中,一个netty服务对应一个端口所有的操作都在一个处理类中,显得过于杂乱。
于是乎,就想着能不能根据传递参数,比如消息中携带一个type
,做不用的处理逻辑跳转。就像适配器一样!
往期回顾
学习本篇博客之前,可以先回顾往期关于springboot 整合 netty
的配置点,此处会做主题配置共用。
Springboot——整合netty并进行websocket通信
代码实现
1、自定义注解
自定义注解只是为了区别哪些bean
对象是需要根据type做区分处理。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // 仅作用于类上
public @interface MyWebSocketTypeHandler {
/**
* 指定类型
* @return
*/
String type() default "";
}
2、自定义子级处理类
目前暂时定义两类处理类,并使用上述自定义注解进行标识。
import cn.xj.annotation.MyWebSocketTypeHandler;
import com.alibaba.fastjson2.JSONObject;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 子级处理类不定义 继承 SimpleChannelInboundHandler 的原因
* https://blog.csdn.net/weixin_29513805/article/details/112705459
*/
@Service
@MyWebSocketTypeHandler(type = "typeA")
public class TypeAHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("TypeA 收到消息处理:"+msg);
Map<String, Object> map = new HashMap<>();
map.put("data","A server 回执:server_A" + msg.toString());
ctx.channel().writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(map)));
}
}
这里之前是继承 SimpleChannelInboundHandler
,但是在实际的调试阶段会报错,出现nettyio.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1异常
。后来参照下列的博客,更改成继承 ChannelInboundHandlerAdapter
得到解决。
https://blog.csdn.net/weixin_29513805/article/details/112705459
typeB
的子级处理与typeA
一样,只是返回信息不同!
3、修改与netty绑定的处理器逻辑
在netty
的配置中,最后的处理类由一个SimpleChannelInboundHandler的子类
处理。如下列的netty配置:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServ