《整合 Spring Boot 和 Netty 实现 WebSocket》 代码写的太完美了!存一个!
立即下载
资源介绍:
《整合 Spring Boot 和 Netty 实现 WebSocket》 代码写的太完美了!存一个!
资源来自:https://blog.csdn.net/dot_life/article/details/136575529
package io.renren.modules.test.nettyweb;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
/**
* @author dongliang7
* @projectName websocket-parent
* @ClassName WebSocketHandler.java
* @description: TODO
* @createTime 2023年02月06日 16:44:00
*/
@Component
@ChannelHandler.Sharable
public class WebSocketHandler extends SimpleChannelInboundHandler {
private static final Logger log = LoggerFactory.getLogger(NettyServer.class);
/**
* 一旦连接,第一个被执行
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
log.info("有新的客户端链接:[{}]", ctx.channel().id().asLongText());
// 添加到channelGroup 通道组
NettyConfig.getChannelGroup().add(ctx.channel());
}
/**
* 读取数据
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
log.info("服务器收到消息:{}", msg.text());
// 获取用户ID,关联channel
JSONObject jsonObject = JSONUtil.parseObj(msg.text());
String uid = jsonObject.getStr("uid");
String touid = jsonObject.getStr("touid");
NettyConfig.getChannelMap().put(uid, ctx.channel());
// 将用户ID作为自定义属性加入到channel中,方便随时channel中获取用户ID
AttributeKey key = AttributeKey.valueOf("userId");
ctx.channel().attr(key).setIfAbsent(uid);
// 回复消息
ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器收到消息啦"));
//然后找找要发给谁
Channel channelToUid = NettyConfig.getChannelMap().get(touid);
if(!ObjectUtils.isEmpty(channelToUid)){
channelToUid.writeAndFlush(new TextWebSocketFrame(jsonObject.getStr("message")) );
}
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
log.info("用户下线了:{}", ctx.channel().id().asLongText());
// 删除通道
NettyConfig.getChannelGroup().remove(ctx.channel());
removeUserId(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.info("异常:{}", cause.getMessage());
// 删除通道
NettyConfig.getChannelGroup().remove(ctx.channel());
removeUserId(ctx);
ctx.close();
}
/**
* 删除用户与channel的对应关系
*/
private void removeUserId(ChannelHandlerContext ctx) {
AttributeKey key = AttributeKey.valueOf("userId");
String userId = ctx.channel().attr(key).get();
NettyConfig.getChannelMap().remove(userId);
}
}