项目
一. linkmaster
1. websocket实现
使用netty实现
ChannelPipeline pipeline = ch.pipeline();
// 因为使用http协议, 需要 http解码器
pipeline.addLast(new ChannelHandler[]{new HttpServerCodec()});
// 以块方式写, 添加 chunkedWriter 处理器
pipeline.addLast(new ChannelHandler[]{new ChunkedWriteHandler()});
/**
* 说明:
* 1. http数据在传输过程中是分段的,HttpObjectAggregator可以把多个段聚合起来;
* 2. 这就是为什么当浏览器发送大量数据时,就会发出多次 http请求的原因
*/
pipeline.addLast(new HttpObjectAggregator(8192));
/**
* 说明:
* 1. 对于 WebSocket,它的数据是以帧frame 的形式传递的;
* 2. 可以看到 WebSocketFrame 下面有6个子类
* 3. 浏览器发送请求时: ws://localhost:7000/hello 表示请求的uri
* 4. WebSocketServerProtocolHandler 核心功能是把 http协议升级为 ws 协议,保持长连接;
* 是通过一个状态码 101 来切换的
*/
pipeline.addLast(new WebSocketServerProtocolHandler("/"));
//30 秒客户端没有向服务端发送心跳则关闭连接,后面是写,和读写
pipeline.addLast(new IdleStateHandler(30, 0, 0));
/**
心跳处理,如果触发了空闲Idle事件,就会处理。通过继承 ChannelInboundHandlerAdapter的userEventTriggered 实现,需要判断触发事件 evt instanceof IdleStateEvent 和 状态 event.state() == IdleState.READER_IDLE
*/
pipeline.addLast(new ChannelHandler[]{new HeartBeatHandler(this.properties)});
/**
自定义消息处理器,继承SimpleChannelInboundHandler<WebSocketFrame> 的 channelRead0方法
需要判断消息是否为文本 WebSocketFrame frame instanceof TextWebSocketFrame
*/
pipeline.addLast(new ChannelHandler[]{new TextMessageHandler()});
2.启动
通过实现ApplicationRunner接口run方法,处理初始化配置和启动,springboot启动后执行。
3.具体过程
客户端:
发送消息json格式,需要传clientId和type,type0握手,1心跳,2关闭连接,其他自定义
服务端:
通过类注解@MessageAccept,注册系统消息接收器。方法注解@type,定义0,1,2
不是系统消息,就实现默认的消息接收器DefaultMessageAcceptor,根据类型查找推送方式去推送
握手和心跳都是通过消息注册器注册,绑定clientId和channel的关系
ChannelRegistryImpl继承Observable,注册和删除时执行notifyObservers方法通知
NativeChannelMapping实现Observer接口,里面维护了concurrentHashMap维护clientId和channel的关系,执行update,判断新增还是删除
二. 登录模块
1.先用账号查找数据库的数据,然后base64去比较密码是否相等
2.通过JWT生成token,载荷audience用用户id,签名的密钥用用户密码去生成
3.redis存放用户id对应的token
4.网关实现了一个token过滤器,根据url匹配过滤需不需要校验
5.从请求头拿出token,通过JWT解析拿出用户id
6.用户id从redis拿出token,在和请求头中的token比较是不是一致,不一致则返回token无效
浙公网安备 33010602011771号