推送消息总结

目前的消息推送方式主要有两种:通知和透传。透传即是透明传送,对于传递的通道来说是不去过问的,通道只负责消息的传递,对消息不做任何处理,当客户端接收到透传消息后,由客户端自己来决定如何处理消息。

以下是发送消息接口

public Map<String, Object> pushNotice(Integer senderId, Integer reciever, String msgContent) {
	//推送消息给用户
        Map<String, Object> dataMap = Maps.newHashMap();
        MessageData data = new MessageData();
        data.setSender(senderId);
        data.setType(UserTypeEnum.APP.getCode());
        data.setReciever(reciever);
        data.setMsgContent(msgContent);
        dataMap.put("type", 1);
        dataMap.put("data", data);
        pushAppManager.pushDataToUser(reciever, dataMap);
        return BaseRespMap.successMap(null);
}
public Map<String, Object> pushDataToUser(Integer reciever, Map<String, Object> dataMap) {
	//用户是否存在登录日志
	bollean isLogin = userDao.isLogin(reciever);
	Map<String, Object> rtnMap = Maps.newHashMap();
	if (isLogin) {
	    Integer deviceType = userDao.getDeviceTypeByUserId(reciever);
	    Map<String, Object> pushMap = userDao.getPushInfoByUserId(reciever);
	    if (null != deviceType) {
		String pusthToken = pushMap.get("pushToken") == null ? "0000000000000000000" : pushMap.get("pushToken").toString();
		Integer iosType = pushMap.get("iosType") == null ? 1 : Integer.parseInt(pushMap.get("iosType").toString());
		pushRouter.apppushTransmissionMsg(deviceType, pusthToken, iosType, dataMap);
		rtnMap = BaseRespMap.successMap(null);
	    }
	} else {
	    //app用户不在线
	    rtnMap = BaseRespMap.deviceOffLine();
	}
	return rtnMap;
}
处理完推送前的逻辑,以下是推送消息,Android采用个推,iOS采用APNs,消息推送采用异步方式
@Async
public PushOutputEntity apppushTransmissionMsg(Integer deviceType, String token, Integer iOSCredentialType, Map<String, Object> dataMap) {
	PushInputEntity pushEntity = new PushInputEntity();
	pushEntity.setTitle(VariableUtils.APP_NAME);
	pushEntity.setSingleChannelId(token);
	pushEntity.setiOSCredentialType(IOSCredentialTypeEnum.getEnum(iOSCredentialType));
	pushEntity.setRawContent(dataMap);
	PushOutputEntity output = null;

	if (DeviceTypeEnum.Android.getCode().equals(deviceType)) {
	    output = androidPushService.pushSingleUniTransmissionMsg(pushEntity);
	} else if (DeviceTypeEnum.IOS.getCode().equals(deviceType)) {
	    output = applePushService.pushSingleUniTransmissionMsg(pushEntity);
	}
	return output;
}
个推
public PushOutputEntity pushSingleUniTransmissionMsg(PushInputEntity pushEntity) {
	if (null == pushEntity || StringUtils.isBlank(pushEntity.getSingleChannelId())) {
	    return null;
	}
	//采用消息透传模板
	TransmissionTemplate template = new TransmissionTemplate();
	template.setAppId(appId);
	template.setAppkey(appKey);
	template.setTransmissionType(TransmissionTypeEnum.START_WAITING.getCode());
	JSONObject json = JSONObject.fromObject(pushEntity.getRawContent());
	template.setTransmissionContent(json.toString());

	SingleMessage message = new SingleMessage();
	message.setOffline(true);
	//离线有效时间,单位为毫秒,可选
	message.setOfflineExpireTime(24 * 3600 * 1000);
	message.setData(template);
	//判断是否客户端是否wifi环境下推送,1为在WIFI环境下,0为不限制网络环境。
	message.setPushNetWorkType(0);
	Target target = new Target();
	target.setAppId(appId);
	target.setClientId(pushEntity.getSingleChannelId());
	push = this.getPush();
	IPushResult ret = null;
	ret = push.pushMessageToSingle(message, target);
	PushOutputEntity pushOutputEntity = new PushOutputEntity();
	if (ret != null) {
	    pushOutputEntity.setMsgId(ret.getMessageId());
	    pushOutputEntity.setResponse(ret.getResponse());
	    pushOutputEntity.setResultCode(ret.getResultCode().name());
	    pushOutputEntity.setTaskId(ret.getTaskId());
	} else {
	    logger.error("服务器响应异常");
	}
	return pushOutputEntity;
}
APNs
public PushOutputEntity pushSingleUniTransmissionMsg(PushInputEntity pushEntity) {
	ApnsService service = getApnsService(pushEntity.getiOSCredentialType(), pushEntity.getSingleChannelId());
	//构造Payload
	PayloadBuilder payloadBuilder = APNS.newPayload();
	payloadBuilder = payloadBuilder.alertBody("").sound("default").badge(1);
	if (null != pushEntity.getRawContent() && pushEntity.getRawContent().size() > 0) {
	    payloadBuilder.customFields(pushEntity.getRawContent());
	}
	String payload = payloadBuilder.build();
	ApnsNotification apnsNotifi1 = service.push(pushEntity.getSingleChannelId(), payload);
	PushOutputEntity outputEntity = new PushOutputEntity();
	Map<String, Object> response = new HashMap<String, Object>();
	try {
	    response.put("payload", new String(apnsNotifi1.getPayload(), "UTF-8"));
	    response.put("expiry", apnsNotifi1.getExpiry());
	    response.put("identifier", apnsNotifi1.getIdentifier());
	} catch (Exception e) {
	    e.printStackTrace();
	}
	outputEntity.setResponse(response);
	outputEntity.setResultCode("OK");
	outputEntity.setSendTime(System.currentTimeMillis());
	return outputEntity;
}
private ApnsService getApnsService(IOSCredentialTypeEnum credential, String channelId) {
        IOSCredentialTypeEnum iosCredential = IOSCredentialTypeEnum.APPSTORE;
        if (null != credential) {
            iosCredential = credential;
        }
        ApnsService service = null;
        boolean isProduction = isProduction(env);
        if (IOSCredentialTypeEnum.APPSTORE.equals(iosCredential)) {
            service = APNS.newService().withCert(appstorePath, appstorePass).withAppleDestination(isProduction).build();
        } else {
            service = APNS.newService().withCert(enterprisePath, enterprisePass).withAppleDestination(isProduction).build();
        }
        return service;
}

移动推送的三种实现方式:
1、轮询方式(PULL)
2、短信推送方式(SMS PUSH)
3、长连接方式(PUSH)

移动 Push 推送基于 TCP 长连接实现, 客户端主动和服务器建立 TCP 长连接之后, 客户端定期向服务器发送心跳包用于保持连接, 有消息的时候, 服务器直接通过这个已经建立好的 TCP 连接通知客户端。尽管长连接也会造成一定的开销,相对于轮询和 SMS 方案的硬伤来说,目前已经是最优的方式,而且通过良好的设计,可以将损耗降至最低。基于 TCP 长连接的方式是主流的推送方式,基于该推送方式逐步发展出系统级、应用级一系列的推送解决方案。

应用级方案(系统级不考虑)
1. 第三方推送服务
鉴于 Android 平台 C2DM 推送的不可用性,国内涌现出大量的第三方推送服务提供商
目前应用最为广泛的第三方推送服务提供商包括个推、极光、友盟、小米、华为、BAT 等,绝大部分 APP 都会优先考虑采用第三方推送服务。
在实际的使用过程中,发现存在以下问题:
1)应用服务端与推送服务强耦合。
2)缺乏 ACK 机制。推送的过程是异步的,从应用服务端发送到推送服务时,可以得知发送是否成功
从第三方推送服务下发到 APP 时,无法得知客户端是否接收到。
3)缺乏消息的持久化。对于推送服务而言,消息推送是来一条推一条,无法追溯历史消息和消息状态。
4)缺乏重传机制。整个推送过程涉及多个环节,当其中某个环节出现问题,造成客户端接收不到推送的消息时,就导致消息丢失,再无法接收到。
5)缺乏数据监控和统计。每个应用每天推送了多少消息,成功到达 app 多少,失败多少,目前均没有统计。

如何构建一套高可用的移动消息推送平台?





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值