ApnsServer.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. package cn.wildfirechat.push.ios;
  2. import cn.wildfirechat.push.PushMessage;
  3. import cn.wildfirechat.push.PushMessageType;
  4. import com.turo.pushy.apns.*;
  5. import com.turo.pushy.apns.metrics.micrometer.MicrometerApnsClientMetricsListener;
  6. import com.turo.pushy.apns.util.ApnsPayloadBuilder;
  7. import com.turo.pushy.apns.util.SimpleApnsPushNotification;
  8. import com.turo.pushy.apns.util.concurrent.PushNotificationFuture;
  9. import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
  10. import io.netty.util.concurrent.Future;
  11. import io.netty.util.concurrent.GenericFutureListener;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.stereotype.Component;
  16. import org.springframework.util.StringUtils;
  17. import javax.annotation.PostConstruct;
  18. import java.io.File;
  19. import java.io.IOException;
  20. import java.util.Calendar;
  21. import java.util.concurrent.ExecutorService;
  22. import java.util.concurrent.Executors;
  23. import static java.lang.System.exit;
  24. @Component
  25. public class ApnsServer {
  26. private static final Logger LOG = LoggerFactory.getLogger(ApnsServer.class);
  27. final SimpleMeterRegistry meterRegistry = new SimpleMeterRegistry();
  28. final MicrometerApnsClientMetricsListener productMetricsListener =
  29. new MicrometerApnsClientMetricsListener(meterRegistry,
  30. "notifications", "apns_product");
  31. final MicrometerApnsClientMetricsListener developMetricsListener =
  32. new MicrometerApnsClientMetricsListener(meterRegistry,
  33. "notifications", "apns_develop");
  34. ApnsClient productSvc;
  35. ApnsClient developSvc;
  36. ApnsClient productVoipSvc;
  37. ApnsClient developVoipSvc;
  38. @Autowired
  39. private ApnsConfig mConfig;
  40. @PostConstruct
  41. private void init() {
  42. if (StringUtils.isEmpty(mConfig.alert)) {
  43. mConfig.alert = "default";
  44. }
  45. if (StringUtils.isEmpty(mConfig.voipAlert)) {
  46. mConfig.alert = "default";
  47. }
  48. try {
  49. productSvc = new ApnsClientBuilder()
  50. .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
  51. .setClientCredentials(new File(mConfig.cerPath), mConfig.cerPwd)
  52. .setMetricsListener(productMetricsListener)
  53. .build();
  54. developSvc = new ApnsClientBuilder()
  55. .setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
  56. .setClientCredentials(new File(mConfig.cerPath), mConfig.cerPwd)
  57. .setMetricsListener(developMetricsListener)
  58. .build();
  59. if (mConfig.voipFeature) {
  60. productVoipSvc = new ApnsClientBuilder()
  61. .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
  62. .setClientCredentials(new File(mConfig.voipCerPath), mConfig.voipCerPwd)
  63. .setMetricsListener(productMetricsListener)
  64. .build();
  65. developVoipSvc = new ApnsClientBuilder()
  66. .setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
  67. .setClientCredentials(new File(mConfig.voipCerPath), mConfig.voipCerPwd)
  68. .setMetricsListener(developMetricsListener)
  69. .build();
  70. }
  71. } catch (IOException e) {
  72. e.printStackTrace();
  73. exit(-1);
  74. }
  75. }
  76. public void pushMessage(PushMessage pushMessage) {
  77. ApnsClient service;
  78. if (pushMessage.getPushType() == IOSPushType.IOS_PUSH_TYPE_DISTRIBUTION) {
  79. if (!mConfig.voipFeature || pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_NORMAL || StringUtils.isEmpty(pushMessage.getVoipDeviceToken())) {
  80. service = productSvc;
  81. } else {
  82. service = productVoipSvc;
  83. }
  84. } else {
  85. if (!mConfig.voipFeature || pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_NORMAL || StringUtils.isEmpty(pushMessage.getVoipDeviceToken())) {
  86. service = developSvc;
  87. } else {
  88. service = developVoipSvc;
  89. }
  90. }
  91. if (service == null) {
  92. LOG.error("Service not exist!!!!");
  93. return;
  94. }
  95. String sound = mConfig.alert;
  96. String pushContent = pushMessage.getPushContent();
  97. boolean hiddenDetail = pushMessage.isHiddenDetail;
  98. if (pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE) {
  99. pushContent = "通话邀请";
  100. sound = mConfig.voipAlert;
  101. hiddenDetail = false;
  102. } else if(pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE) {
  103. pushContent = "通话结束";
  104. sound = null;
  105. hiddenDetail = false;
  106. } else if(pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_VOIP_ANSWER) {
  107. pushContent = "已被其他端接听";
  108. sound = null;
  109. hiddenDetail = false;
  110. }
  111. int badge = pushMessage.getUnReceivedMsg();
  112. if (badge <= 0) {
  113. badge = 1;
  114. }
  115. String title;
  116. String body;
  117. //todo 这里需要加上语言的处理,客户端会上报自己的语言,在DeviceInfo那个类中
  118. // if (pushMessage.language == "zh_CN") {
  119. //
  120. // } else if(pushMessage.language == "US_EN") {
  121. //
  122. // }
  123. if (pushMessage.convType == 1) {
  124. title = pushMessage.targetName;
  125. if (StringUtils.isEmpty(title)) {
  126. title = "群聊";
  127. }
  128. if (StringUtils.isEmpty(pushMessage.senderName)) {
  129. body = pushContent;
  130. } else {
  131. body = pushMessage.senderName + ":" + pushContent;
  132. }
  133. if (hiddenDetail) {
  134. body = "你收到一条新消息"; //Todo 需要判断当前语言
  135. }
  136. if (pushMessage.mentionedType == 1) {
  137. if (StringUtils.isEmpty(pushMessage.senderName)) {
  138. body = "有人在群里@了你";
  139. } else {
  140. body = pushMessage.senderName + "在群里@了你";
  141. }
  142. } else if(pushMessage.mentionedType == 2) {
  143. if (StringUtils.isEmpty(pushMessage.senderName)) {
  144. body = "有人在群里@了大家";
  145. } else {
  146. body = pushMessage.senderName + "在群里@了大家";
  147. }
  148. }
  149. } else {
  150. if (pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_FRIEND_REQUEST) {
  151. if (StringUtils.isEmpty(pushMessage.senderName)) {
  152. title = "好友请求";
  153. } else {
  154. title = pushMessage.senderName + " 请求加您为好友";
  155. }
  156. } else {
  157. if (StringUtils.isEmpty(pushMessage.senderName)) {
  158. title = "消息";
  159. } else {
  160. title = pushMessage.senderName;
  161. }
  162. }
  163. if (hiddenDetail) {
  164. body = "你收到一条新消息"; //Todo 需要判断当前语言
  165. } else {
  166. body = pushContent;
  167. }
  168. }
  169. final ApnsPayloadBuilder payloadBuilder = new ApnsPayloadBuilder();
  170. payloadBuilder.setAlertBody(body);
  171. payloadBuilder.setAlertTitle(title);
  172. payloadBuilder.setBadgeNumber(badge);
  173. payloadBuilder.setSound(sound);
  174. final String payload = payloadBuilder.buildWithDefaultMaximumLength();
  175. final String token;
  176. if (service == productVoipSvc || service == developVoipSvc) {
  177. token = pushMessage.voipDeviceToken;
  178. } else {
  179. token = pushMessage.deviceToken;
  180. }
  181. Calendar c = Calendar.getInstance();
  182. ApnsPushNotification pushNotification;
  183. if (!mConfig.voipFeature || pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_NORMAL || StringUtils.isEmpty(pushMessage.getVoipDeviceToken())) {
  184. if(pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_NORMAL || StringUtils.isEmpty(pushMessage.getVoipDeviceToken())) {
  185. c.add(Calendar.MINUTE, 10); //普通推送
  186. pushNotification = new SimpleApnsPushNotification(token, pushMessage.packageName, payload, c.getTime(), DeliveryPriority.CONSERVE_POWER, PushType.ALERT);
  187. } else {
  188. c.add(Calendar.MINUTE, 1); //voip通知,使用普通推送
  189. pushNotification = new SimpleApnsPushNotification(token, pushMessage.packageName, payload, c.getTime(), DeliveryPriority.IMMEDIATE, PushType.ALERT);
  190. }
  191. } else {
  192. c.add(Calendar.MINUTE, 1);
  193. pushNotification = new SimpleApnsPushNotification(token, pushMessage.packageName + ".voip", payload, c.getTime(), DeliveryPriority.IMMEDIATE, PushType.VOIP);
  194. }
  195. final PushNotificationFuture<ApnsPushNotification, PushNotificationResponse<ApnsPushNotification>>
  196. sendNotificationFuture = service.sendNotification(pushNotification);
  197. sendNotificationFuture.addListener(new GenericFutureListener<Future<? super PushNotificationResponse<ApnsPushNotification>>>() {
  198. @Override
  199. public void operationComplete(Future<? super PushNotificationResponse<ApnsPushNotification>> future) throws Exception {
  200. // When using a listener, callers should check for a failure to send a
  201. // notification by checking whether the future itself was successful
  202. // since an exception will not be thrown.
  203. if (future.isSuccess()) {
  204. final PushNotificationResponse<ApnsPushNotification> pushNotificationResponse =
  205. sendNotificationFuture.getNow();
  206. // Handle the push notification response as before from here.
  207. } else {
  208. // Something went wrong when trying to send the notification to the
  209. // APNs gateway. We can find the exception that caused the failure
  210. // by getting future.cause().
  211. future.cause().printStackTrace();
  212. }
  213. }
  214. });
  215. }
  216. }