Commit e75e7675 by giaogiao

消息在线推送;

parent c9550ee2
......@@ -17,7 +17,7 @@ public class SignTest {
/**
* 获取sign,客户端sdk得到sign之后就可以进行登录,websocket连接初始化需要带上sign,验证通过才能连接成功
* <p>
* sign = MD5{ clientId + appKey + appSecret}
* sign = MD5{timestemp + clientId + appKey + appSecret}
*
* @param appKey
* @param appSecret
......@@ -31,13 +31,12 @@ public class SignTest {
}
public static void main(String[] args) throws JsonProcessingException {
String clientId = "hahah_31";
public static void main(String[] args) {
String clientId = "client_111";
String appKey = "elLwpel1gWCHDqZy";
String appSecret = "68809bb5a9077a83631aeb0b17b5965d6b2302faf2ab3737";
String timestemp = String.valueOf(new Date().getTime());
getSign(timestemp, clientId, appKey, appSecret);
// jsonTest();
}
private static void jsonTest() throws JsonProcessingException {
......
......@@ -61,7 +61,9 @@ public class ImMessage extends BaseEntity {
@ApiModelProperty("at他人,传入客户端id数组")
private String at;
@ApiModelProperty("发送状态, 0AVIMMessageStatusNone(未知) 1AVIMMessageStatusSending(发送中) 2AVIMMessageStatusSent(发送成功) 3AVIMMessageStatusReceipt(被接收) 4AVIMMessageStatusFailed(失败)")
@ApiModelProperty("1 AVIMMessageStatusSending(发送中)" +
"2 AVIMMessageStatusSent(发送成功)" +
"3 AVIMMessageStatusFailed(失败)")
private Integer sendStatus;
@ApiModelProperty("会话id")
......
package com.wecloud.im.entity;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.HashMap;
/**
* 消息在线推送
*
* @author wei
* @since 2021-04-29
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "ImMessageOnlineSend ")
public class ImMessageOnlineSend extends BaseEntity {
private static final long serialVersionUID = 1L;
@NotNull(message = "消息id不能为空")
@ApiModelProperty("消息id")
private Long msgId;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("撤回时间")
private Date withdrawTime;
@ApiModelProperty("发送者客户端id")
private String sender;
@ApiModelProperty("内容")
private HashMap content;
@ApiModelProperty("0未撤回; 1已撤回")
private Boolean withdraw;
@ApiModelProperty("0非事件; 1为事件")
private Boolean event;
@ApiModelProperty("0非系统通知; 1为系统通知")
private Boolean system;
@ApiModelProperty("at他人,传入客户端id数组")
private String at;
@ApiModelProperty("会话id")
private Long conversationId;
}
......@@ -108,6 +108,9 @@ public class ImClientLoginServiceImpl implements ImClientLoginService {
TokenVo tokenVo = new TokenVo();
tokenVo.setToken(generateToken);
tokenVo.setId(imClient.getId());
tokenVo.setAttributes(imClient.getAttributes());
return ApiResult.ok(tokenVo);
}
......
......@@ -12,13 +12,23 @@ import java.io.Serializable;
*/
@Data
@Accessors(chain = true)
public class ResponseModel implements Serializable {
public class ResponseModel<T> implements Serializable {
/**
* 下发在线消息
*/
public static final Integer ONLINE_MSG = 2;
/**
* 响应数据
*/
public static final Integer RES = 1;
/**
* 枚举类UriPathEnum 请求uri的编码
* 由于websocket使用同一个通道发送数据,需要区分不同类型请求
*/
private long path;
private Integer cmd;
/**
* 状态码
......@@ -33,7 +43,7 @@ public class ResponseModel implements Serializable {
/**
* json数据
*/
private Object data;
private T data;
/**
* 请求id, 以判空是否发送成功, 服务端处理完成后返回
......
......@@ -2,8 +2,8 @@ package com.wecloud.im.tillo.app_ws.service;
import com.wecloud.im.tillo.app_ws.model.ResponseModel;
import com.wecloud.im.tillo.app_ws.model.ResultStatus;
import com.wecloud.im.tillo.app_ws.model.request.ReceiveModel;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
/**
* @Description ws响应数据,各种状态码封装
......@@ -15,51 +15,39 @@ public interface WriteDataService {
/**
* 可自定义状态码 带data
*
* @param requestModel
* @param resultStatus
* @param receiveModel
* @param data
* @param userId
* @param language
*/
void dataAndStatus(ReceiveModel requestModel, ResultStatus resultStatus, Object data, Long userId, String language);
void dataAndStatus(ReceiveModel receiveModel, ApiCode apiCode, Object data, String toAppKey, String toClientId);
/**
* 固定"成功"状态码 带data
*
* @param requestModel
* @param data
* @param userId
* @param language
*/
void successAndData(ReceiveModel requestModel, Object data, Long userId, String language);
void successAndData(ReceiveModel requestModel, Object data, String toAppKey, String toClientId);
/**
* 固定"成功"状态码 无data
*
* @param requestModel
* @param resultStatus
* @param userId
* @param language
*/
void nullDataSuccess(ReceiveModel requestModel, ResultStatus resultStatus, Long userId, String language);
void nullDataSuccess(ReceiveModel requestModel, ApiCode apiCode, String toAppKey, String toClientId);
/**
* 固定"参数错误"状态码 无data
*
* @param requestModel
* @param userId
* @param language
*/
void paramErrorAndNullData(ReceiveModel requestModel, Long userId, String language);
void paramErrorAndNullData(ReceiveModel requestModel, String toAppKey, String toClientId);
/**
* 调用ws处理响应逻辑
*
* @param responseModel
* @param userId
*/
void write(ResponseModel responseModel, Long userId);
void write(ResponseModel responseModel, String toAppKey, String toClientId);
}
package com.wecloud.im.tillo.app_ws.service.impl;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.wecloud.im.tillo.app_ws.model.ResponseModel;
import com.wecloud.im.tillo.app_ws.model.ResultStatus;
import com.wecloud.im.tillo.app_ws.model.request.ReceiveModel;
import com.wecloud.im.tillo.app_ws.service.MangerChannelService;
import com.wecloud.im.tillo.app_ws.service.WriteDataService;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
......@@ -17,42 +21,50 @@ import java.util.HashMap;
@Component
public class WriteDataServiceImpl implements WriteDataService {
// @Autowired
// private MangerChannelService mangerChannelService;
@Autowired
private MangerChannelService mangerChannelService;
@Override
public void successAndData(ReceiveModel requestModel, Object data, Long userId, String language) {
this.dataAndStatus(requestModel, ResultStatus.SUCCESS, data, userId, language);
public void successAndData(ReceiveModel receiveModel, Object data, String toAppKey, String toClientId) {
this.dataAndStatus(receiveModel, ApiCode.SUCCESS, data, toAppKey, toClientId);
}
@Override
public void nullDataSuccess(ReceiveModel requestModel, ResultStatus resultStatus, Long userId, String language) {
this.dataAndStatus(requestModel, resultStatus, new HashMap<>(1), userId, language);
public void nullDataSuccess(ReceiveModel receiveModel, ApiCode apiCode, String toAppKey, String toClientId) {
this.dataAndStatus(receiveModel, apiCode, new HashMap<>(1), toAppKey, toClientId);
}
@Override
public void paramErrorAndNullData(ReceiveModel requestModel, Long userId, String language) {
// this.nullDataSuccess(requestModel, ResultStatus.PARAM_ERROR, userId, language);
public void paramErrorAndNullData(ReceiveModel receiveModel, String toAppKey, String toClientId) {
// this.nullDataSuccess(requestModel, ResultStatus.PARAM_ERROR, userId);
}
@Override
public void dataAndStatus(ReceiveModel requestModel, ResultStatus resultStatus, Object data, Long userId, String language) {
// ResultModel<String> resultModel = new ResultModel<>(resultStatus, language);
//
// ResponseModel responseModel = new ResponseModel();
// responseModel.setMsg(resultModel.getMessage());
// responseModel.setPath(requestModel.getPath());
// responseModel.setReqId(requestModel.getReqId());
// responseModel.setData(data);
// responseModel.setCode(resultModel.getStatus());
// this.write(responseModel, userId);
public void dataAndStatus(ReceiveModel receiveModel, ApiCode apiCode, Object data, String toAppKey, String toClientId) {
ApiResult<Boolean> apiResult = ApiResult.result(apiCode);
ResponseModel responseModel = new ResponseModel();
responseModel.setMsg(apiResult.getMessage());
responseModel.setCmd(receiveModel.getCmd());
responseModel.setReqId(receiveModel.getReqId());
responseModel.setData(data);
responseModel.setCode(apiResult.getCode());
this.write(responseModel, toAppKey, toClientId);
}
@Override
public void write(ResponseModel responseModel, Long userId) {
String json = JSON.toJSONString(responseModel);
// mangerChannelService.writeData(json, userId);
public void write(ResponseModel responseModel, String toAppKey, String toClientId) {
JsonMapper jsonMapper = new JsonMapper();
String json = null;
try {
json = jsonMapper.writeValueAsString(responseModel);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
mangerChannelService.writeData(json, toAppKey, toClientId);
}
}
package com.wecloud.im.tillo.app_ws.strategy.concrete;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
......@@ -8,6 +7,7 @@ import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.entity.ImInbox;
import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.entity.ImMessageOnlineSend;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.service.ImConversationMembersService;
......@@ -15,17 +15,22 @@ import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.tillo.app_ws.annotation.ReceiveTypeAnnotation;
import com.wecloud.im.tillo.app_ws.enums.WsRequestCmdEnum;
import com.wecloud.im.tillo.app_ws.model.ResponseModel;
import com.wecloud.im.tillo.app_ws.model.request.ReceiveModel;
import com.wecloud.im.tillo.app_ws.service.MangerChannelService;
import com.wecloud.im.tillo.app_ws.service.WriteDataService;
import com.wecloud.im.tillo.app_ws.strategy.AbstractReceiveStrategy;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.shiro.util.SnowflakeUtil;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
......@@ -34,7 +39,10 @@ import java.util.List;
@ReceiveTypeAnnotation(type = WsRequestCmdEnum.DATA)
@Service
@Slf4j
public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
public class ImConcreteReceiveStrategy extends AbstractReceiveStrategy {
@Autowired
private WriteDataService writeDataService;
@Autowired
private ImMessageService imMessageService;
......@@ -45,8 +53,6 @@ public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
@Autowired
private ImApplicationService imApplicationService;
@Resource
private MangerChannelService mangerChannelService;
@Autowired
private ImConversationMembersService imConversationMembersService;
......@@ -55,7 +61,7 @@ public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
private ImClientService imClientService;
@Override
public void process(ReceiveModel requestModel, String language, ChannelHandlerContext ctx, String data) {
public void process(ReceiveModel receiveModel, String language, ChannelHandlerContext ctx, String data) {
String appKey = ctx.channel().attr(MangerChannelService.APP_KEY).get();
String clientUniId = ctx.channel().attr(MangerChannelService.CLIENT_ID).get();
......@@ -63,20 +69,29 @@ public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
// 查询imApplication
ImApplication imApplication = imApplicationService.getOne(new QueryWrapper<ImApplication>().lambda()
.eq(ImApplication::getAppKey, appKey));
if (imApplication == null) {
log.error("imApplication为空");
return;
}
// 查询发送者client
ImClient imClientSender = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getClientId, clientUniId));
if (imClientSender == null) {
log.error("imClientSender为空");
return;
}
JsonMapper jsonMapper = new JsonMapper();
Long toConversationId = Long.valueOf(requestModel.getData().get("toConversation").toString());
Long toConversationId = Long.valueOf(receiveModel.getData().get("toConversation").toString());
receiveModel.getData().remove("toConversation");
long messageId = SnowflakeUtil.getId();
String content = null;
try {
content = jsonMapper.writeValueAsString(requestModel.getData());
content = jsonMapper.writeValueAsString(receiveModel.getData());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
......@@ -85,16 +100,13 @@ public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
ImMessage imMessage = new ImMessage();
imMessage.setId(messageId);
imMessage.setCreateTime(new Date());
// imMessage.setWithdrawTime(new Date());
// imMessage.setUpdateDate(new Date());
imMessage.setFkAppid(imApplication.getId());
imMessage.setSender(imClientSender.getId());
imMessage.setContent(content);
imMessage.setWithdraw(false);
imMessage.setEvent(false);
imMessage.setSystem(false);
// imMessage.setAt("");
imMessage.setSendStatus(0);
imMessage.setSendStatus(2);
imMessage.setFkConversationId(toConversationId);
imMessageService.save(imMessage);
......@@ -109,13 +121,20 @@ public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
return;
}
for (ImConversationMembers conversationMembers : membersList) {
// 封装响应的实体
ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend();
BeanUtils.copyProperties(imMessage, imMessageOnlineSend);
imMessageOnlineSend.setMsgId(imMessage.getId());
imMessageOnlineSend.setSender(clientUniId);
imMessageOnlineSend.setContent(receiveModel.getData());
imMessageOnlineSend.setConversationId(toConversationId);
// 遍历发送
for (ImConversationMembers conversationMembers : membersList) {
// 排除发送者
if (conversationMembers.getFkClientId().equals(imClientSender.getId())) {
continue;
}
// 保存收件箱
long imInboxId = SnowflakeUtil.getId();
ImInbox imInbox = new ImInbox();
......@@ -128,14 +147,39 @@ public class SingleConcreteReceiveStrategy extends AbstractReceiveStrategy {
imInbox.setFkConversationId(toConversationId);
imInboxService.save(imInbox);
// 接收方
// 查询接收方
ImClient imClientReceiver = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getId, conversationMembers.getFkClientId()));
if (imClientReceiver == null) {
return;
}
// 向接收方推送
String imClientRecerverUniId = imClientReceiver.getClientId();
mangerChannelService.writeData(content, appKey, imClientRecerverUniId);
ResponseModel<ImMessageOnlineSend> responseModel = new ResponseModel<>();
responseModel.setCmd(ResponseModel.RES);
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(imMessageOnlineSend);
responseModel.setReqId(null);
writeDataService.write(responseModel, appKey, imClientReceiver.getClientId());
}
// 响应发送方消息id等信息
ResponseModel<HashMap<String, Long>> responseModel = new ResponseModel<>();
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCmd(ResponseModel.ONLINE_MSG);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
HashMap<String, Long> stringHashMap = new HashMap<String, Long>();
stringHashMap.put("msgId", messageId);
responseModel.setData(stringHashMap);
responseModel.setReqId(receiveModel.getReqId());
writeDataService.write(responseModel, appKey, clientUniId);
}
}
package com.wecloud.im.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
......@@ -8,5 +9,12 @@ import java.io.Serializable;
@Data
public class TokenVo implements Serializable {
String token;
private String token;
@ApiModelProperty("客户端id")
private Long id;
@ApiModelProperty("可选 自定义属性,供开发者扩展使用。")
private String attributes;
}
......@@ -18,13 +18,11 @@ package io.geekidea.springbootplus.framework.common.api;
import io.geekidea.springbootplus.framework.config.il8n.I18nMessageUtil;
import io.geekidea.springbootplus.framework.config.il8n.LanguageEnum;
import io.geekidea.springbootplus.framework.util.HttpServletRequestUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
......@@ -50,10 +48,6 @@ public class ApiResult<T> implements Serializable {
* 响应码
*/
private int code;
// /**
// * 是否成功
// */
// private boolean success;
/**
* 响应消息
......@@ -97,12 +91,12 @@ public class ApiResult<T> implements Serializable {
// }
// 多语言国际化,根据http上下文, 取得heard中的language语言属性,实现不用在业务代码中传递语言字段
HttpServletRequest request = HttpServletRequestUtil.getRequest();
String language = request.getHeader("language");
// HttpServletRequest request = HttpServletRequestUtil.getRequest();
// String language = request.getHeader("language");
String success = "SUCCESS";
try {
message = I18nMessageUtil.getMessage(LanguageEnum.getLanguageType(language), apiCode.getMessage(), success);
message = I18nMessageUtil.getMessage(LanguageEnum.getLanguageType(null), apiCode.getMessage(), success);
} catch (IOException e) {
message = success;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment