lines = IOUtils.readLines(in, urlConnection.getContentEncoding());
138 | StringBuffer strBuf = new StringBuffer();
139 | for (String line : lines) {
140 | strBuf.append(line);
141 | }
142 | // LOG.info(strBuf.toString());
143 | return strBuf.toString();
144 | } finally {
145 | IOUtils.closeQuietly(outPut);
146 | IOUtils.closeQuietly(in);
147 | if (urlConnection != null) {
148 | urlConnection.disconnect();
149 | }
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/hm/payload/AlertPayload.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.hm.payload;
2 |
3 | import cn.wildfirechat.push.PushMessage;
4 | import cn.wildfirechat.push.PushMessageType;
5 | import cn.wildfirechat.push.Utility;
6 | import cn.wildfirechat.push.hm.payload.internal.ClickAction;
7 | import cn.wildfirechat.push.hm.payload.internal.Notification;
8 | import cn.wildfirechat.push.hm.payload.internal.Payload;
9 | import cn.wildfirechat.push.hm.payload.internal.Target;
10 | import com.google.gson.Gson;
11 | import org.json.simple.JSONObject;
12 |
13 | import java.text.MessageFormat;
14 | import java.util.ArrayList;
15 |
16 |
17 | public class AlertPayload {
18 | Payload payload;
19 | Target target;
20 |
21 | @Override
22 | public String toString() {
23 | return new Gson().toJson(this);
24 | }
25 |
26 | public static AlertPayload buildAlertPayload(PushMessage pushMessage) {
27 | Notification notification = new Notification();
28 | String[] titleAndBody = Utility.getPushTitleAndContent(pushMessage);
29 | notification.title = titleAndBody[0];
30 | notification.body = titleAndBody[1];
31 |
32 | ClickAction clickAction = new ClickAction();
33 |
34 | if (pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_NORMAL) {
35 | JSONObject data = new JSONObject();
36 | JSONObject conv = new JSONObject();
37 | conv.put("type", pushMessage.convType);
38 | conv.put("target", pushMessage.target);
39 | conv.put("line", pushMessage.line);
40 | data.put("conversation", conv);
41 | clickAction.data = data;
42 | } else {
43 | // TODO
44 | }
45 |
46 | notification.clickAction = clickAction;
47 |
48 | Target target = new Target();
49 | target.token = new ArrayList<>();
50 | target.token.add(pushMessage.deviceToken);
51 |
52 | AlertPayload alertPayload = new AlertPayload();
53 | alertPayload.payload = new Payload();
54 | alertPayload.payload.notification = notification;
55 | alertPayload.target = target;
56 |
57 | return alertPayload;
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/hm/payload/VoipPayload.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.hm.payload;
2 |
3 | import cn.wildfirechat.push.PushMessage;
4 | import cn.wildfirechat.push.hm.payload.internal.Payload;
5 | import cn.wildfirechat.push.hm.payload.internal.Target;
6 | import com.google.gson.Gson;
7 |
8 | import java.util.ArrayList;
9 |
10 |
11 | public class VoipPayload {
12 | Payload payload;
13 | Target target;
14 |
15 | @Override
16 | public String toString() {
17 | return new Gson().toJson(this);
18 | }
19 |
20 | public static VoipPayload buildAlertPayload(PushMessage pushMessage) {
21 | Target target = new Target();
22 | target.token = new ArrayList<>();
23 | target.token.add(pushMessage.deviceToken);
24 |
25 | VoipPayload voipPayload = new VoipPayload();
26 | voipPayload.payload = new Payload();
27 | voipPayload.payload.extraData = "TODO";
28 | voipPayload.target = target;
29 |
30 | return voipPayload;
31 | }
32 | }
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/hm/payload/internal/ClickAction.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.hm.payload.internal;
2 |
3 | import org.json.simple.JSONObject;
4 |
5 | public class ClickAction {
6 | /**
7 | * 0:打开应用首页
8 | *
9 | * 1:打开应用自定义页面
10 | */
11 | public int actionType;
12 |
13 | public String action;
14 | public String uri;
15 | public JSONObject data;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/hm/payload/internal/Notification.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.hm.payload.internal;
2 |
3 | public class Notification {
4 | public String category = "IM";
5 | public String title;
6 | public String body;
7 | public ClickAction clickAction;
8 | public int style;
9 | public String image;
10 | public Integer notifyId;
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/hm/payload/internal/Payload.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.hm.payload.internal;
2 |
3 | public class Payload {
4 | public Notification notification;
5 | public String extraData;
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/hm/payload/internal/Target.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.hm.payload.internal;
2 |
3 | import java.util.ArrayList;
4 |
5 | public class Target {
6 | public ArrayList token;
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/ios/ApnsConfig.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.ios;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.context.annotation.PropertySource;
6 |
7 | @Configuration
8 | @ConfigurationProperties(prefix="apns")
9 | @PropertySource(value = "file:config/apns.properties")
10 | public class ApnsConfig {
11 | String cerPath;
12 | String cerPwd;
13 |
14 | String authKeyPath;
15 | String keyId;
16 | String teamId;
17 |
18 | String voipCerPath;
19 | String voipCerPwd;
20 |
21 | String alert;
22 | String voipAlert;
23 |
24 | boolean voipFeature;
25 |
26 | public String getCerPath() {
27 | return cerPath;
28 | }
29 |
30 | public void setCerPath(String cerPath) {
31 | this.cerPath = cerPath;
32 | }
33 |
34 | public String getCerPwd() {
35 | return cerPwd;
36 | }
37 |
38 | public void setCerPwd(String cerPwd) {
39 | this.cerPwd = cerPwd;
40 | }
41 |
42 | public String getVoipCerPath() {
43 | return voipCerPath;
44 | }
45 |
46 | public void setVoipCerPath(String voipCerPath) {
47 | this.voipCerPath = voipCerPath;
48 | }
49 |
50 | public String getVoipCerPwd() {
51 | return voipCerPwd;
52 | }
53 |
54 | public void setVoipCerPwd(String voipCerPwd) {
55 | this.voipCerPwd = voipCerPwd;
56 | }
57 |
58 | public String getAlert() {
59 | return alert;
60 | }
61 |
62 | public void setAlert(String alert) {
63 | this.alert = alert;
64 | }
65 |
66 | public String getVoipAlert() {
67 | return voipAlert;
68 | }
69 |
70 | public void setVoipAlert(String voipAlert) {
71 | this.voipAlert = voipAlert;
72 | }
73 |
74 | public boolean isVoipFeature() {
75 | return voipFeature;
76 | }
77 |
78 | public void setVoipFeature(boolean voipFeature) {
79 | this.voipFeature = voipFeature;
80 | }
81 |
82 | public String getAuthKeyPath() {
83 | return authKeyPath;
84 | }
85 |
86 | public void setAuthKeyPath(String authKeyPath) {
87 | this.authKeyPath = authKeyPath;
88 | }
89 |
90 | public String getKeyId() {
91 | return keyId;
92 | }
93 |
94 | public void setKeyId(String keyId) {
95 | this.keyId = keyId;
96 | }
97 |
98 | public String getTeamId() {
99 | return teamId;
100 | }
101 |
102 | public void setTeamId(String teamId) {
103 | this.teamId = teamId;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/ios/ApnsServer.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.ios;
2 |
3 | import cn.wildfirechat.push.PushMessage;
4 | import cn.wildfirechat.push.PushMessageType;
5 | import cn.wildfirechat.push.Utility;
6 | import com.turo.pushy.apns.*;
7 | import com.turo.pushy.apns.auth.ApnsSigningKey;
8 | import com.turo.pushy.apns.metrics.micrometer.MicrometerApnsClientMetricsListener;
9 | import com.turo.pushy.apns.util.ApnsPayloadBuilder;
10 | import com.turo.pushy.apns.util.SimpleApnsPushNotification;
11 | import com.turo.pushy.apns.util.concurrent.PushNotificationFuture;
12 | import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
13 | import org.json.simple.JSONObject;
14 | import org.json.simple.parser.JSONParser;
15 | import org.json.simple.parser.ParseException;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 | import org.springframework.beans.factory.annotation.Autowired;
19 | import org.springframework.stereotype.Component;
20 | import org.springframework.util.StringUtils;
21 |
22 | import javax.annotation.PostConstruct;
23 | import java.io.File;
24 | import java.util.*;
25 |
26 | @Component
27 | public class ApnsServer {
28 | private static final Logger LOG = LoggerFactory.getLogger(ApnsServer.class);
29 |
30 | final SimpleMeterRegistry meterRegistry = new SimpleMeterRegistry();
31 | final MicrometerApnsClientMetricsListener productMetricsListener =
32 | new MicrometerApnsClientMetricsListener(meterRegistry,
33 | "notifications", "apns_product");
34 | final MicrometerApnsClientMetricsListener developMetricsListener =
35 | new MicrometerApnsClientMetricsListener(meterRegistry,
36 | "notifications", "apns_develop");
37 |
38 | ApnsClient productSvc;
39 | ApnsClient developSvc;
40 | ApnsClient productVoipSvc;
41 | ApnsClient developVoipSvc;
42 |
43 | @Autowired
44 | private ApnsConfig mConfig;
45 |
46 | @PostConstruct
47 | private void init() {
48 | if (StringUtils.isEmpty(mConfig.alert)) {
49 | mConfig.alert = "default";
50 | }
51 |
52 | if (StringUtils.isEmpty(mConfig.voipAlert)) {
53 | mConfig.alert = "default";
54 | }
55 |
56 | try {
57 | if (!StringUtils.isEmpty(mConfig.authKeyPath) && !StringUtils.isEmpty(mConfig.keyId) && !StringUtils.isEmpty(mConfig.teamId)) {
58 | productSvc = new ApnsClientBuilder()
59 | .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
60 | .setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File(mConfig.authKeyPath), mConfig.teamId, mConfig.keyId))
61 | .setMetricsListener(productMetricsListener)
62 | .build();
63 |
64 | developSvc = new ApnsClientBuilder()
65 | .setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
66 | .setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File(mConfig.authKeyPath), mConfig.teamId, mConfig.keyId))
67 | .setMetricsListener(developMetricsListener)
68 | .build();
69 |
70 | if (mConfig.voipFeature) {
71 | productVoipSvc = new ApnsClientBuilder()
72 | .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
73 | .setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File(mConfig.authKeyPath), mConfig.teamId, mConfig.keyId))
74 | .setMetricsListener(productMetricsListener)
75 | .build();
76 | developVoipSvc = new ApnsClientBuilder()
77 | .setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
78 | .setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File(mConfig.authKeyPath), mConfig.teamId, mConfig.keyId))
79 | .setMetricsListener(developMetricsListener)
80 | .build();
81 | }
82 | } else {
83 | productSvc = new ApnsClientBuilder()
84 | .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
85 | .setClientCredentials(new File(mConfig.cerPath), mConfig.cerPwd)
86 | .setMetricsListener(productMetricsListener)
87 | .build();
88 |
89 | developSvc = new ApnsClientBuilder()
90 | .setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
91 | .setClientCredentials(new File(mConfig.cerPath), mConfig.cerPwd)
92 | .setMetricsListener(developMetricsListener)
93 | .build();
94 |
95 | if (mConfig.voipFeature) {
96 | productVoipSvc = new ApnsClientBuilder()
97 | .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
98 | .setClientCredentials(new File(mConfig.voipCerPath), mConfig.voipCerPwd)
99 | .setMetricsListener(productMetricsListener)
100 | .build();
101 | developVoipSvc = new ApnsClientBuilder()
102 | .setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
103 | .setClientCredentials(new File(mConfig.voipCerPath), mConfig.voipCerPwd)
104 | .setMetricsListener(developMetricsListener)
105 | .build();
106 | }
107 | }
108 | } catch (Exception e) {
109 | LOG.error("ApnsServer init failed");
110 | e.printStackTrace();
111 | }
112 | }
113 |
114 | public long getMessageId(PushMessage pushMessage) {
115 | try {
116 | JSONObject jsonObject = (JSONObject)(new JSONParser().parse(pushMessage.pushData));
117 | if(jsonObject.get("messageUid") instanceof Long) {
118 | return (Long)jsonObject.get("messageUid");
119 | } else if(jsonObject.get("messageUid") instanceof Integer) {
120 | return (Integer)jsonObject.get("messageUid");
121 | } else if(jsonObject.get("messageUid") instanceof Double) {
122 | double uid = (Double)jsonObject.get("messageUid");
123 | return (long)uid;
124 | }
125 | } catch (ParseException e) {
126 | e.printStackTrace();
127 | }
128 | return 0;
129 | }
130 |
131 | private static class TimeUUID {
132 | UUID uuid;
133 | long timestamp;
134 |
135 | public TimeUUID(UUID uuid) {
136 | this.uuid = uuid;
137 | this.timestamp = System.currentTimeMillis();
138 | }
139 | }
140 |
141 | private Map callPushId = new HashMap<>();
142 |
143 | private synchronized void addCallPushId(long callId, UUID uuid) {
144 | callPushId.put(callId, new TimeUUID(uuid));
145 |
146 | //remove history record
147 | Iterator> iterator = callPushId.entrySet().iterator();
148 | long now = System.currentTimeMillis();
149 | while (iterator.hasNext()) {
150 | Map.Entry entry = iterator.next();
151 | if (now - entry.getValue().timestamp > 10*60*1000) {
152 | iterator.remove();
153 | }
154 | }
155 | }
156 |
157 | private synchronized UUID getCallPushId(long callId) {
158 | TimeUUID timeUUID = callPushId.remove(callId);
159 | if (timeUUID != null) {
160 | return timeUUID.uuid;
161 | }
162 | return null;
163 | }
164 |
165 | public void pushMessage(PushMessage pushMessage) {
166 | ApnsClient service;
167 | String sound = mConfig.alert;
168 |
169 | String collapseId = null;
170 | if(pushMessage.messageId > 0) {
171 | collapseId = pushMessage.messageId + "";
172 | }
173 |
174 | boolean isCallInvite = pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE;
175 |
176 | if (isCallInvite) {
177 | sound = mConfig.voipAlert;
178 | } else if(pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE || pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_VOIP_ANSWER) {
179 | if (pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE && pushMessage.callStartUid > 0) {
180 | collapseId = pushMessage.callStartUid + "";
181 | }
182 | sound = null;
183 | } else if(pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_RECALLED || pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_DELETED) {
184 | sound = null;
185 | long messageId = getMessageId(pushMessage);
186 | if(messageId > 0) {
187 | collapseId = messageId + "";
188 | }
189 | } else if(pushMessage.pushMessageType != PushMessageType.PUSH_MESSAGE_TYPE_NORMAL && pushMessage.pushMessageType != PushMessageType.PUSH_MESSAGE_TYPE_SECRET_CHAT) {
190 | LOG.error("not support push message type:{}", pushMessage.pushMessageType);
191 | }
192 |
193 | int badge = pushMessage.getUnReceivedMsg();
194 | if (badge <= 0) {
195 | badge = 1;
196 | }
197 |
198 | String[] arr = Utility.getPushTitleAndContent(pushMessage);
199 | String title = arr[0];
200 | String body = arr[1];
201 |
202 | final ApnsPayloadBuilder payloadBuilder = new ApnsPayloadBuilder();
203 | payloadBuilder.setAlertBody(body);
204 | payloadBuilder.setAlertTitle(title);
205 | payloadBuilder.setBadgeNumber(badge);
206 | payloadBuilder.setSound(sound);
207 | JSONObject jsonObject = new JSONObject();
208 | jsonObject.put("sender", pushMessage.sender);
209 | jsonObject.put("convType", pushMessage.convType);
210 | jsonObject.put("convTarget", pushMessage.target);
211 | jsonObject.put("convLine", pushMessage.line);
212 | jsonObject.put("contType", pushMessage.cntType);
213 | jsonObject.put("pushData", pushMessage.pushData);
214 | payloadBuilder.addCustomProperty("wfc", jsonObject);
215 |
216 | Calendar c = Calendar.getInstance();
217 | ApnsPushNotification pushNotification;
218 |
219 | UUID apnsId = null;
220 |
221 | if(pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE && pushMessage.callStartUid > 0) {
222 | apnsId = getCallPushId(pushMessage.callStartUid);
223 | }
224 |
225 | if (!mConfig.voipFeature || pushMessage.pushMessageType != PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE) {
226 | if (pushMessage.getPushType() == IOSPushType.IOS_PUSH_TYPE_DISTRIBUTION) {
227 | service = productSvc;
228 | } else {
229 | service = developSvc;
230 | }
231 | if(pushMessage.pushMessageType != PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE || StringUtils.isEmpty(pushMessage.getVoipDeviceToken())) {
232 | c.add(Calendar.MINUTE, 10); //普通推送
233 | String payload = payloadBuilder.buildWithDefaultMaximumLength();
234 | pushNotification = new SimpleApnsPushNotification(pushMessage.deviceToken, pushMessage.packageName, payload, c.getTime(), DeliveryPriority.CONSERVE_POWER, PushType.ALERT, collapseId, apnsId);
235 | } else {
236 | c.add(Calendar.MINUTE, 1); //voip通知,使用普通推送
237 | payloadBuilder.setContentAvailable(true);
238 | payloadBuilder.addCustomProperty("voip", true);
239 | payloadBuilder.addCustomProperty("voip_type", pushMessage.pushMessageType);
240 | payloadBuilder.addCustomProperty("voip_data", pushMessage.pushData);
241 | String payload = payloadBuilder.buildWithDefaultMaximumLength();
242 | pushNotification = new SimpleApnsPushNotification(pushMessage.deviceToken, pushMessage.packageName, payload, c.getTime(), DeliveryPriority.IMMEDIATE, PushType.BACKGROUND, collapseId, apnsId);
243 | }
244 | } else {
245 | if (pushMessage.getPushType() == IOSPushType.IOS_PUSH_TYPE_DISTRIBUTION) {
246 | service = productVoipSvc;
247 | } else {
248 | service = developVoipSvc;
249 | }
250 | c.add(Calendar.MINUTE, 1);
251 | String payload = payloadBuilder.buildWithDefaultMaximumLength();
252 | pushNotification = new SimpleApnsPushNotification(pushMessage.voipDeviceToken, pushMessage.packageName + ".voip", payload, c.getTime(), DeliveryPriority.IMMEDIATE, PushType.VOIP, collapseId, apnsId);
253 | }
254 |
255 | SimpleApnsPushNotification simpleApnsPushNotification = (SimpleApnsPushNotification)pushNotification;
256 | LOG.info("CollapseId:{}", simpleApnsPushNotification.getCollapseId());
257 |
258 | if (service == null) {
259 | LOG.error("Service not exist!!!!");
260 | return;
261 | }
262 |
263 | final PushNotificationFuture> sendNotificationFuture = service.sendNotification(pushNotification);
264 | sendNotificationFuture.addListener(future -> {
265 | // When using a listener, callers should check for a failure to send a
266 | // notification by checking whether the future itself was successful
267 | // since an exception will not be thrown.
268 | if (future.isSuccess()) {
269 | final PushNotificationResponse pushNotificationResponse =
270 | sendNotificationFuture.getNow();
271 | if(!pushNotificationResponse.isAccepted()) {
272 | LOG.error("apns push failure: {}", pushNotificationResponse.getRejectionReason());
273 | } else {
274 | LOG.info("push success: {}", pushNotificationResponse.getApnsId().toString());
275 | LOG.info("token invalidate timestamp: {}", pushNotificationResponse.getTokenInvalidationTimestamp());
276 |
277 | if (isCallInvite) {
278 | addCallPushId(pushMessage.messageId, pushNotificationResponse.getApnsId());
279 | }
280 | }
281 | } else {
282 | // Something went wrong when trying to send the notification to the
283 | // APNs gateway. We can find the exception that caused the failure
284 | // by getting future.cause().
285 | future.cause().printStackTrace();
286 | LOG.error("apns push failure: {}", future.cause().getLocalizedMessage());
287 | }
288 | });
289 | }
290 | }
291 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/ios/IOSPushService.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.ios;
2 |
3 | import cn.wildfirechat.push.PushMessage;
4 |
5 | public interface IOSPushService {
6 | Object push(PushMessage pushMessage);
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/ios/IOSPushServiceImpl.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.ios;
2 |
3 | import cn.wildfirechat.push.PushMessage;
4 | import cn.wildfirechat.push.PushMessageType;
5 | import cn.wildfirechat.push.Utility;
6 | import cn.wildfirechat.push.android.AndroidPushType;
7 | import cn.wildfirechat.push.android.getui.GetuiPush;
8 | import com.google.gson.Gson;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Service;
13 |
14 | import java.util.concurrent.ExecutorService;
15 | import java.util.concurrent.SynchronousQueue;
16 | import java.util.concurrent.ThreadPoolExecutor;
17 | import java.util.concurrent.TimeUnit;
18 |
19 | @Service
20 | public class IOSPushServiceImpl implements IOSPushService {
21 | private static final Logger LOG = LoggerFactory.getLogger(IOSPushServiceImpl.class);
22 | @Autowired
23 | public ApnsServer apnsServer;
24 |
25 | @Autowired
26 | private GetuiPush getuiPush;
27 |
28 | private ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors() * 100,
29 | 60L, TimeUnit.SECONDS,
30 | new SynchronousQueue());
31 |
32 | @Override
33 | public Object push(PushMessage pushMessage) {
34 | LOG.info("iOS push {}", new Gson().toJson(pushMessage));
35 | if(Utility.filterPush(pushMessage)) {
36 | LOG.info("canceled");
37 | return "Canceled";
38 | }
39 | final long start = System.currentTimeMillis();
40 | executorService.execute(()->{
41 | long now = System.currentTimeMillis();
42 | if (now - start > 15000) {
43 | LOG.error("等待太久,消息抛弃");
44 | return;
45 | }
46 | if(pushMessage.pushType < 3) {
47 | apnsServer.pushMessage(pushMessage);
48 | } else if(pushMessage.pushType == AndroidPushType.ANDROID_PUSH_TYPE_GETUI) {
49 | getuiPush.push(pushMessage, false);
50 | } else {
51 | LOG.error("Unknown ios push type: {}", pushMessage.pushType);
52 | }
53 |
54 | });
55 | return "OK";
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/push/ios/IOSPushType.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.push.ios;
2 |
3 | public interface IOSPushType {
4 | int IOS_PUSH_TYPE_DISTRIBUTION = 0;
5 | int IOS_PUSH_TYPE_DEVELOPEMENT = 1;
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/libs/MiPush_SDK_Server_2_2_19.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wildfirechat/push_server/554618ab8cf9af501c47eea7a2f8999ae8f572ce/src/main/libs/MiPush_SDK_Server_2_2_19.jar
--------------------------------------------------------------------------------
/src/main/libs/httpclient-4.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wildfirechat/push_server/554618ab8cf9af501c47eea7a2f8999ae8f572ce/src/main/libs/httpclient-4.5.jar
--------------------------------------------------------------------------------
/src/main/libs/httpcore-4.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wildfirechat/push_server/554618ab8cf9af501c47eea7a2f8999ae8f572ce/src/main/libs/httpcore-4.4.1.jar
--------------------------------------------------------------------------------
/src/main/libs/opush-server-sdk-1.0.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wildfirechat/push_server/554618ab8cf9af501c47eea7a2f8999ae8f572ce/src/main/libs/opush-server-sdk-1.0.4.jar
--------------------------------------------------------------------------------
/src/main/libs/vPush-server-sdk-1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wildfirechat/push_server/554618ab8cf9af501c47eea7a2f8999ae8f572ce/src/main/libs/vPush-server-sdk-1.0.jar
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8085
2 | logging.level.root=debug
3 | logging.file=push.log
4 |
--------------------------------------------------------------------------------