设计要点
1.web,app注册系统同时注册极光IM
2.WEB集成IM sdk,用户WEB登录与极光IM建立长连接
3.后端调用极光IM API给WEB用户推送消息,并将信息存入持久化到DB
4.用户下载登录app,自动注册极光统计用户,并与极光jpush云建立长连接
5.后端调用极光JPUSH API给APP用户推送消息,并将信息存入持久化到DB
后端核心代码
1.依赖
<!--极光JPUSH-->
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.3.10</version>
</dependency>
<!--极光IM-->
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jmessage-client</artifactId>
<version>1.1.8</version>
</dependency>
2.核心Java代码 :IM 注册,删除,WEB推送,APP推送
/**
* 极光IM:极光IM用户通过JMessageClient的接口进行注册(管理平台"im用户"+1,可管理),web集成IM sdk建立长连接,服务器JMessageClient调用推送接口进行web推送
* 极光JPUSH:APP内集成jpush,且用户需要安装APP才能收到消息(安装后管理平台"统计用户"+1)。用户后台进程被杀死也不能收到消息,可考虑厂商通道。
*
* @author majun
* @version 1.0
* @date 2020-08-13 21:50
*/
@Component
@Setter
@Slf4j
@ConfigurationProperties(prefix = "jpush")
public class JiguangClient {
private String vehicleV2Key;
private String vehicleV2Secret;
private UserClient vehicleV2UserClient; //极光IM用户client
private JMessageClient vehicleV2JmessageClient;//极光IM消息client(web推送),是UserClient的增强
private JPushClient vehicleV2JpushClient;//极光Android-iOS消息推送client
@PostConstruct
private void init() {
vehicleV2JpushClient = new JPushClient(vehicleV2Secret, vehicleV2Key); //注意两个对象参数顺序不一样
vehicleV2UserClient = new UserClient(vehicleV2Key, vehicleV2Secret);
vehicleV2JmessageClient = new JMessageClient(vehicleV2Key, vehicleV2Secret);
}
/**
* 删除极光IM用户,删除失败不影响正常业务,这里就不抛出异常了
*
* @param tel
* @return
*/
public void deleteUser(String tel) {
ResponseWrapper responseWrapper = null;
try {
responseWrapper = vehicleV2UserClient.deleteUser(tel);
if (responseWrapper.responseCode != 204) {
log.warn("极光用户删除失败", e);
}
} catch (APIConnectionException e) {
log.error("极光用户删除失败", e);
} catch (APIRequestException e) {
log.warn("用户已可能已不存在", e);
}
}
/**
* 注册极光IM用户
*
* @param tel
* @return
*/
public void registUser(String tel) {
RegisterPayload payload =
RegisterPayload.newBuilder().addUsers(RegisterInfo.newBuilder()
.setUsername(tel)
.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()))
.build()).build();
ResponseWrapper responseWrapper = null;
try {
responseWrapper = vehicleV2UserClient.registerUsers(payload);
Assert.isTrue(responseWrapper.responseCode == 201, "极光用户新增失败");
} catch (APIConnectionException e) {
log.error("极光用户新增失败", e);
throw new CommonException("极光用户新增失败");
} catch (APIRequestException e) {
log.warn("请勿重复注册", e);
Assert.isTrue(e.getErrorCode() == 899001, "极光用户新增失败");
}
}
/**
* 获取极光payload(建立极光长连接需要)
*
* @return
*/
public Map<String, Object> getJMPayload() {
Map<String, Object> map = new HashMap<>();
String uuid = UUID.randomUUID().toString();
Long timestamp = Calendar.getInstance().getTimeInMillis();
String signature =
DigestUtils.md5DigestAsHex(
("appkey="
+ vehicleV2Key
+ "×tamp="
+ timestamp
+ "&random_str="
+ UUID.randomUUID().toString()
+ "&key="
+ vehicleV2Secret).getBytes());
map.put("appkey", vehicleV2Key);
map.put("random_str", uuid);
map.put("timestamp", timestamp);
map.put("signature", signature);
return map;
}
/**
* 发送极光app消息,如版本更新信息,通过Jpush client推送
*
* @param phones
* @param msg
*/
public void sendNotice2Users(String titile, String msg, List<String> phones) {
PushPayload pushPayload = buildPayloadV2(phones, msg, titile, null, null);
PushResult pushResult = null;
try {
pushResult = vehicleV2JpushClient.sendPush(pushPayload);
Assert.isTrue(pushResult.isResultOK(), "后台进程信息推送失败");
} catch (Exception e) {
log.error("后台进程信息推送失败",e);
throw new CommonException("极光后台进程信息推送失败");
}
}
/**
* 发送极光web消息,通过IM client推送
*
* @param map
* @throws CommonException
*/
private void sendWebJMessage(Map<String, String> map) throws CommonException {
MessageBody body = new MessageBody.Builder().setText(map.get("text")).addExtras(map).build();
MessagePayload payload = MessagePayload.newBuilder()
.setVersion(1)
.setTargetType("single")
.setTargetId(map.get("targetId"))
.setFromType("admin")
.setFromId("constxxxxx")
.setMessageType(MessageType.TEXT)
.setMessageBody(body)
.build();
SendMessageResult result = null;
try {
result = vehicleV2JmessageClient.sendMessage(payload);
Assert.isTrue(result.isResultOK(), "发送极光web消息失败");
} catch (Exception e) {
log.error("发送极光web消息失败", e);
throw new CommonException("发送极光web消息失败");
}
}
public static PushPayload buildPayloadV2(Collection<String> phones, String msg,String tittle, @Nullable String sound, @Nullable Map<String, String> extas) {
extas = extas == null ? extas = new HashMap<>(2) : extas;
return PushPayload.newBuilder()
.setPlatform(Platform.android_ios())
.setAudience(Audience.alias(phones))
.setMessage(Message.newBuilder().setMsgContent(msg).addExtras(extas).build())
.setNotification(
Notification.newBuilder()
.addPlatformNotification(
AndroidNotification.newBuilder()
.addExtras(extas)
.setAlert(tittle)
.build())
.addPlatformNotification(
IosNotification.newBuilder()
.addExtras(extas)
.setSound(sound == null ? "default" : sound)
.setAlert(tittle)
.build())
.build())
.setOptions(
Options.newBuilder()
.setApnsProduction(true) // true-推送生产环境 false-推送开发环境(测试使用参数)
.setTimeToLive(90) // 消息在JPush服务器的失效时间(测试使用参数)
.build())
.build();
}
public static void main(String[] args) throws APIConnectionException, APIRequestException {
//几个client
JPushClient vehicleV2JpushClient_prod = new JPushClient("xxxxxxxxcf", "73c3610cdxxx7a");//极光Android-iOS消息推送client
JMessageClient vehicleV2JmessageClient = new JMessageClient("xxxxx863ace90", "5c897c3c2xxxxxd1");//极光IM通讯client(web推送)
UserClient vehicleV2UserClient = new UserClient("89xxx2863ace90", "5c89xxxx908fa32512d1");//极光IM通讯client(web推送)
//新增/删除IM用户
vehicleV2JmessageClient.deleteUser("181112xxx17");
vehicleV2JmessageClient.deleteUser("18111xxx017");
// vehicleV2UserClient.deleteUser("1811xxxxxx");
// ResponseWrapper registerUsers = vehicleV2JmessageClient.registerUsers(RegisterPayload.newBuilder().addUsers(RegisterInfo.newBuilder()
// .setUsername("181xxx017")
// .setPassword(DigestUtils.md5DigestAsHex("7758965421561".getBytes()))
// .build()).build());
// UserInfoResult userInfo = vehicleV2JmessageClient.getUserInfo("181xxxx017");
//测试推送
PushPayload pushPayload = buildPayloadV2(Lists.newArrayList("18111xxxx", "181xxxx"), "测试内容", "测试标题",null, null);
vehicleV2JpushClient_prod.sendPush(pushPayload);
}
}