对于t-io的消息处理主要通过下面的类来完成
其中
1、handshake 这个部分是握手,这里前端传入用户,根据用户进行tio的绑定与群组绑定;
2、onText 这个对于消息的处理,对心跳,正常消息等进行处理
代码如下:
@Component
public class TioWsMsgHandler implements IWsMsgHandler {
private static final Logger log = LoggerFactory.getLogger(TioWsMsgHandler.class);
public static TioConfig tioConfig;
@Resource
private IImUserService imUserService;
@Resource
private IImMessageService iImMessageService;
@Resource
private IImThirdService iImThirdService;
/**
* 握手时走这个方法,业务可以在这里获取cookie,request参数等
*
* @param request request
* @param httpResponse httpResponse
* @param channelContext channelContext
* @return HttpResponse
*/
@Override
public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext) {
tioConfig = channelContext.tioConfig;
String userName = request.getParam("name");
SysUser loginUser = iImThirdService.getUserByName(userName);
if(Objects.isNull(loginUser)) {
log.info("handshake:" + "无法获得登录用户信息!");
return httpResponse;
}
//String userName = loginUser.getUsername();
// 先关闭原先的连接
Tio.closeUser(tioConfig, userName, null);
// 绑定用户
Tio.bindUser(channelContext, userName);
// 在线用户绑定到上下文 用于发送在线消息
WsOnlineContext.bindUser(userName, channelContext);
// 绑定群组
List<ImChatGroup> groups = imUserService.getChatGroups(userName);
for (ImChatGroup group : groups) {
Tio.bindGroup(channelContext, group.getId());
}
return httpResponse;
}
/**
* @param httpRequest httpRequest
* @param httpResponse httpResponse
* @param channelContext channelContext
* @throws Exception Exception
* @author tanyaowu tanyaowu
*/
@Override
public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
}
/**
* 字节消息(binaryType = arraybuffer)过来后会走这个方法
*/
@Override
public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
return null;
}
/**
* 当客户端发close flag时,会走这个方法
*/
@Override
public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
Tio.remove(channelContext, "receive close flag");
return null;
}
/**
* 字符消息(binaryType = blob)过来后会走这个方法
*
* @param wsRequest wsRequest
* @param text text
* @param channelContext channelContext
* @return obj
*/
@Override
public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) {
try {
ObjectMapper objectMapper = new ObjectMapper();
SendInfo sendInfo = objectMapper.readValue(text, SendInfo.class);
System.out.println("onText " + text);
//心跳检测包
if (ChatUtils.MSG_PING.equals(sendInfo.getCode())) {
WsResponse wsResponse = WsResponse.fromText(text, TioServerConfig.CHARSET);
Tio.send(channelContext, wsResponse);
}
//真正的消息
else if (ChatUtils.MSG_MESSAGE.equals(sendInfo.getCode())) {
Message message = sendInfo.getMessage();
message.setMine(false);
WsResponse wsResponse = WsResponse.fromText(objectMapper.writeValueAsString(sendInfo), TioServerConfig.CHARSET);
//单聊
if (ChatUtils.MESSAGE_TYPE_FRIEND.equals(message.getType())) {
SetWithLock<ChannelContext> channelContextSetWithLock = Tio.getByUserid(channelContext.tioConfig, message.getId());
//用户没有登录,存储到离线文件
if (channelContextSetWithLock == null || channelContextSetWithLock.size() == 0) {
saveMessage(message, ChatUtils.READ_TYPE_UNREAD);
} else {
Tio.sendToUser(channelContext.tioConfig, message.getId(), wsResponse);
//入库操作
saveMessage(message, ChatUtils.READ_TYPE_READ);
}
if("admin".equals(message.getId())){
SendInfo sendInfo1 = ObjectUtil.cloneByStream (sendInfo);
Message message1 = sendInfo1.getMessage();
message1.setUsername("管理员");
message1.setAvatar("http://192.168.199.152:9010/nbcio/temp/nbcio_1660480947146.png");
message1.setMine(false);
message1.setId(message.getFromname());
message1.setFromname("admin");
message1.setContent("欢迎使用NBCIO 亿事达企业管理平台!");
sendInfo1.setMessage(message1);
WsResponse wsResponse1 = WsResponse.fromText(objectMapper.writeValueAsString(sendInfo1), TioServerConfig.CHARSET);
Tio.sendToUser(channelContext.tioConfig, message.getFromname(), wsResponse1);
}
} else {
Tio.sendToGroup(channelContext.tioConfig, message.getId(), wsResponse);
//入库操作
saveMessage(message, ChatUtils.READ_TYPE_READ);
}
}
//准备就绪,需要发送离线消息
else if (ChatUtils.MSG_READY.equals(sendInfo.getCode())) {
//未读消息
sendOffLineMessage(channelContext, objectMapper);
}
} catch (IOException e) {
e.printStackTrace();
}
//返回值是要发送给客户端的内容,一般都是返回null
return null;
}
/**
* 未读消息
*
* @param channelContext channelContext
* @param objectMapper objectMapper
* @throws IOException 抛出异常
*/
private void sendOffLineMessage(ChannelContext channelContext, ObjectMapper objectMapper) throws IOException {
List<ImMessage> imMessageList = iImMessageService.getUnReadMessage(channelContext.userid);
for (ImMessage imMessage : imMessageList) {
Message message = new Message();
message.setId(imMessage.getToName());
message.setMine(false);
message.setType(imMessage.getType());
SysUser imUser = imUserService.getByName(imMessage.getFromName());
message.setUsername(imUser.getUsername());
message.setCid(String.valueOf(imMessage.getId()));
message.setContent(imMessage.getContent());
message.setTimestamp(System.currentTimeMillis());
message.setFromname(imMessage.getFromName());
message.setAvatar(imUser.getAvatar());
SendInfo sendInfo1 = new SendInfo();
sendInfo1.setCode(ChatUtils.MSG_MESSAGE);
sendInfo1.setMessage(message);
WsResponse wsResponse = WsResponse.fromText(objectMapper.writeValueAsString(sendInfo1), TioServerConfig.CHARSET);
Tio.sendToUser(channelContext.tioConfig, message.getId(), wsResponse);
}
}
/**
* 保存信息
*
* @param message 信息
* @param readStatus 是否已读
*/
private void saveMessage(Message message, String readStatus) {
ImMessage imMessage = new ImMessage();
imMessage.setToName(message.getUsername());
imMessage.setFromName(message.getFromname());
imMessage.setSendTime(System.currentTimeMillis());
imMessage.setContent(message.getContent());
imMessage.setReadStatus(readStatus);
imMessage.setType(message.getType());
iImMessageService.saveMessage(imMessage);
}
}