Attributes.java
import io.netty.util.AttributeKey;
/**
* 通道中的自定义属性
*/
public interface Attributes {
/**
* 用户控制用户是否登录 newInstance创建一个给定名称为login的key,如果已存在则会报错
*/
AttributeKey<Boolean> LOGIN=AttributeKey.newInstance("login");
/**
* 用户存储用户信息到通道中
*/
AttributeKey<User> USER=AttributeKey.newInstance("user");
}
JsonUtil.java
import com.alibaba.fastjson.JSON;
public class JsonUtil {
/**
* 对象处理
*
* @param msg 数据
* @param classs 实体类class
* @return 对象
*/
public static Object parseObject(Object msg, Class classs) {
Object o = JSON.parseObject(msg.toString(), classs);
return o;
}
/**
* 对象处理
*
* @param nettyMessage 数据
* @return 对象
*/
public static Object parseNettyMessage(Object nettyMessage) {
Object obj = null;
String msgString = nettyMessage.toString();
msgString = msgString.replaceAll("\\\\", "");
msgString = msgString.substring(1, msgString.length() - 1);
//先取出类型
int typeIndex = msgString.indexOf("transportType");
//当前用户对象
int userIndex = msgString.indexOf("user");
//传输的用户组
int otherUsersIndex = msgString.lastIndexOf("otherUsers");
String substring = "";
if (userIndex != -1 && otherUsersIndex != -1) {
substring = msgString.substring(typeIndex + 16, userIndex - 3);
} else {
substring = msgString.substring(typeIndex + 16, msgString.length() - 2);
}
StringBuffer stringBuffer = new StringBuffer(msgString);
if (substring.equals(TransportType.OBJECT.getValue())) {
int first = msgString.indexOf(",");
int last = msgString.lastIndexOf(",");
stringBuffer = stringBuffer.replace(first + 7, first + 9, "{").replace(last - 3, last - 1, "}");
obj = JSON.parseObject(stringBuffer.toString(), NettyMessage.class);
} else if (substring.equals(TransportType.STRING.getValue()) || substring.equals(TransportType.HEARTBEAT.getValue())) {
int msgIndex = msgString.indexOf("msg");
int otherUsers = msgString.indexOf("otherUsers");
if (otherUsers != -1) {
stringBuffer = stringBuffer.replace(msgIndex + 5, msgIndex + 7, "\"").replace(otherUsersIndex - 5, otherUsersIndex - 3, "\"");
} else {
int lastIndex = msgString.lastIndexOf(",");
stringBuffer = stringBuffer.replace(msgIndex + 5, msgIndex + 7, "\"").replace(lastIndex - 3, lastIndex - 1, "\"");
}
obj = JSON.parseObject(stringBuffer.toString(), NettyMessage.class);
} else {
obj = JSON.parseObject(msgString, NettyMessage.class);
}
return obj;
}
public static String stringMsg(Object msg) {
String stringMsg = msg.toString().substring(1, msg.toString().length() - 1);
return stringMsg;
}
public static boolean booleanToJson(Object msg) {
Boolean booleanMsg = Boolean.valueOf(msg.toString());
return booleanMsg;
}
public static String objectToJson(Object object) {
String body = JSON.toJSONString(object);
return body;
}
}
LoginUtil.java
import io.netty.channel.Channel;
import io.netty.util.Attribute;
/**
* 用于设置以及判断是否有标志位,如果有标志位,不管标志为值是什么,都表示已经成功登录过。
*/
public class LoginUtil {
/**
* 给通道设置LOGIN的值 登录了为true
*
* @param channel 通道
*/
public static void markAsLogin(Channel channel) {
channel.attr(Attributes.LOGIN).set(true);
}
/**
* 查询LOGIN的值 登录了为true
*
* @param channel 通道
* @return 状态
*/
public static boolean hasLogin(Channel channel) {
Attribute<Boolean> loginAttr = channel.attr(Attributes.LOGIN);
return loginAttr.get() != null ;
}
/**
* 用户退出登录状态
* @param channel 通道
*/
public static void logoOut(Channel channel) {
channel.attr(Attributes.LOGIN).set(null);
}
}
NettyConstants.java
TransportType.java
public class NettyConstants {
public static int LOCAL_PORT = 8080;
public static String LOCAL_IP = "127.0.0.1";
public static int REMOTE_PORT = 8080;
public static String REMOTE_IP = "127.0.0.1";
}
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* msg 传输类型
*/
@NoArgsConstructor
@AllArgsConstructor
@Getter
public enum TransportType {
STRING("string类型","string"),
OBJECT("object类型","object"),
FLAG("flag类型","flag"),
HEARTBEAT("心跳机制","heartbeat");
private String msg;
private String value;
}
UserChannelUtil.java
import io.netty.channel.Channel;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 用户通道绑定
*/
public class UserChannelUtil {
/**
* 将用户与通道关联信息存在map中
*/
public static final Map<String, Channel> userIdChannelMap = new ConcurrentHashMap<>();
/**
* 将用户信息绑定至管道中
* @param user 用户
* @param channel
*/
public static void bindUser(User user, Channel channel) {
userIdChannelMap.put(user.getUserId(), channel);
channel.attr(Attributes.USER).set(user);
}
/**
* 程序退出时解除绑定
* @param channel
*/
public static void unBindUser(Channel channel) {
if (hasLogin(channel)) {
userIdChannelMap.remove(getUser(channel).getUserId());
channel.attr(Attributes.USER).set(null);
}
}
/**
* 判断通道中是否存在用户信息,存在则已经登录
*/
public static boolean hasLogin(Channel channel) {
return channel.hasAttr(Attributes.USER);
}
/**
* 从通道中获取USER属性
*/
public static User getUser(Channel channel) {
return channel.attr(Attributes.USER).get();
}
/**
* 通过用户ID获取通道
*/
public static Channel getChannel(String userId) {
return userIdChannelMap.get(userId);
}
public static User user(){
User user = new User("蝙蝠侠","admin","test");
return user;
}
}
代码已上传至github:https://github.com/beibeirenzhe/netty-im/tree/master/fyrtim