From 1b262657c9790dbaa0b9738639bf30f8d87d4b4f Mon Sep 17 00:00:00 2001 From: maksim <154536744@qq.com> Date: Mon, 16 May 2016 13:58:18 +0800 Subject: [PATCH 01/53] duplicate project name with mpush-client --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3dd00e1..0f16a7c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 9 com.mpush - mpush-client + mpush-client-java 0.0.3 jar From 63d6451f42788e52d9246e11c18584be285dd253 Mon Sep 17 00:00:00 2001 From: ohun Date: Wed, 24 Aug 2016 12:04:04 +0800 Subject: [PATCH 02/53] Update README.md --- README.md | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5ac9f66..35cacab 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,35 @@ -# mpush-client-java -mpush java client +## 介绍 +#### mpush-client-java是一个纯java实现的一个MPUS客户端,不依赖其他任何第三方框架。 + +## 用途 +#### 主要用于android sdk底层通信,该工程本身不包含任何android相关代码。 + +## 源码测试 + +参见 `com.mpush.client.MPushClientTest.java` +```java +public class MPushClientTest { + private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB"; + private static final String allocServer = "http://127.0.0.1:9999/"; + + public static void main(String[] args) throws Exception { + Client client = ClientConfig + .build() + .setPublicKey(publicKey) + .setAllotServer(allocServer) + .setDeviceId("1111111111") + .setOsName("Android") + .setOsVersion("6.0") + .setClientVersion("2.0") + .setUserId("doctor43test") + .setSessionStorageDir(MPushClientTest.class.getResource("/").getFile()) + .setLogger(new DefaultLogger()) + .setLogEnabled(true) + .setEnableHttpProxy(false) + .setClientListener(new L()) + .create(); + client.start(); + + LockSupport.park(); + } +``` From b431d72f1bafc4652930c97ad089659497f561c0 Mon Sep 17 00:00:00 2001 From: ohun Date: Wed, 24 Aug 2016 12:10:07 +0800 Subject: [PATCH 03/53] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 35cacab..e0f4828 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ ## 源码测试 -参见 `com.mpush.client.MPushClientTest.java` +参见 [`com.mpush.client.MPushClientTest.java`](https://github.com/mpusher/mpush-client-java/blob/master/src/test/java/com/mpush/client/MPushClientTest.java) ```java public class MPushClientTest { - private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB"; - private static final String allocServer = "http://127.0.0.1:9999/"; + private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB";//公钥对应服务端的私钥 + private static final String allocServer = "http://127.0.0.1:9999/";//用于获取MPUSH server的ip:port, 用于负载均衡 public static void main(String[] args) throws Exception { Client client = ClientConfig @@ -33,3 +33,4 @@ public class MPushClientTest { LockSupport.park(); } ``` +#### 说明allocServer的实现参照[AllocServer.java](https://github.com/mpusher/alloc/blob/master/src/main/java/com/shinemo/mpush/alloc/AllocServer.java) From 9544abc4563e5dcba8c51ea9f1b5be0fc63f2d0b Mon Sep 17 00:00:00 2001 From: ohun Date: Thu, 25 Aug 2016 09:32:44 +0800 Subject: [PATCH 04/53] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index e0f4828..ff4df33 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,15 @@ ## 用途 #### 主要用于android sdk底层通信,该工程本身不包含任何android相关代码。 +## 当前版本 +```xml + + com.github.mpusher + mpush-client + 0.0.4 + +``` + ## 源码测试 参见 [`com.mpush.client.MPushClientTest.java`](https://github.com/mpusher/mpush-client-java/blob/master/src/test/java/com/mpush/client/MPushClientTest.java) From e1a1c03e362b8175b639e613748aae4cd9be4c33 Mon Sep 17 00:00:00 2001 From: ohun Date: Thu, 25 Aug 2016 09:34:16 +0800 Subject: [PATCH 05/53] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ff4df33..d5bcc6d 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,11 @@ #### 主要用于android sdk底层通信,该工程本身不包含任何android相关代码。 ## 当前版本 + +```groovy +compile group: 'com.github.mpusher', name: 'mpush-client', version: '0.0.4' +``` + ```xml com.github.mpusher From 17f8f8c06fbb359461253be9d4829aa2a69d25ee Mon Sep 17 00:00:00 2001 From: ohun Date: Thu, 25 Aug 2016 09:36:31 +0800 Subject: [PATCH 06/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5bcc6d..3e721d4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## 当前版本 ```groovy -compile group: 'com.github.mpusher', name: 'mpush-client', version: '0.0.4' +compile 'com.github.mpusher:mpush-client:0.0.4' ``` ```xml From 5b4bfaf3cb7e8f73f271d50f904a4eaf8697cb6d Mon Sep 17 00:00:00 2001 From: ohun Date: Sat, 27 Aug 2016 09:19:08 +0800 Subject: [PATCH 07/53] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3e721d4..67ed25a 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,14 @@ ## 当前版本 ```groovy -compile 'com.github.mpusher:mpush-client:0.0.4' +compile 'com.github.mpusher:mpush-client-java:0.0.2' ``` ```xml com.github.mpusher - mpush-client - 0.0.4 + mpush-client-java + 0.0.2 ``` From 94e7e54cfd03fe01966b994654265da65e4102af Mon Sep 17 00:00:00 2001 From: ohun Date: Sat, 27 Aug 2016 09:20:11 +0800 Subject: [PATCH 08/53] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 67ed25a..7c76cc5 100644 --- a/README.md +++ b/README.md @@ -47,4 +47,6 @@ public class MPushClientTest { LockSupport.park(); } ``` -#### 说明allocServer的实现参照[AllocServer.java](https://github.com/mpusher/alloc/blob/master/src/main/java/com/shinemo/mpush/alloc/AllocServer.java) +#### 说明: + +allocServer的实现参照[AllocServer.java](https://github.com/mpusher/alloc/blob/master/src/main/java/com/shinemo/mpush/alloc/AllocServer.java) From cd36db46991d71d6c22bc3f599aad61345f002e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Tue, 6 Sep 2016 18:19:33 +0800 Subject: [PATCH 09/53] add ACK --- .../java/com/mpush/api/ClientListener.java | 2 +- .../java/com/mpush/api/protocol/Command.java | 1 + .../com/mpush/api/protocol/MPushProtocol.java | 2 + .../java/com/mpush/api/protocol/Packet.java | 10 ++-- .../mpush/client/DefaultClientListener.java | 4 +- .../java/com/mpush/client/MPushClient.java | 20 +++++--- .../com/mpush/handler/PushMessageHandler.java | 11 ++++- .../java/com/mpush/message/AckMessage.java | 46 +++++++++++++++++++ .../java/com/mpush/message/PushMessage.java | 8 ++++ .../com/mpush/client/MPushClientTest.java | 8 ++-- 10 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/mpush/message/AckMessage.java diff --git a/src/main/java/com/mpush/api/ClientListener.java b/src/main/java/com/mpush/api/ClientListener.java index bf7658c..4773ec3 100644 --- a/src/main/java/com/mpush/api/ClientListener.java +++ b/src/main/java/com/mpush/api/ClientListener.java @@ -33,7 +33,7 @@ public interface ClientListener { void onHandshakeOk(Client client, int heartbeat); - void onReceivePush(Client client, byte[] content); + void onReceivePush(Client client, byte[] content, int messageId); void onKickUser(String deviceId, String userId); } diff --git a/src/main/java/com/mpush/api/protocol/Command.java b/src/main/java/com/mpush/api/protocol/Command.java index 55ff9a1..18aa70d 100644 --- a/src/main/java/com/mpush/api/protocol/Command.java +++ b/src/main/java/com/mpush/api/protocol/Command.java @@ -48,6 +48,7 @@ public enum Command { GATEWAY_CHAT(20), GROUP(21), GATEWAY_GROUP(22), + ACK(23), UNKNOWN(-1); Command(int cmd) { diff --git a/src/main/java/com/mpush/api/protocol/MPushProtocol.java b/src/main/java/com/mpush/api/protocol/MPushProtocol.java index 47a51de..72b32a0 100644 --- a/src/main/java/com/mpush/api/protocol/MPushProtocol.java +++ b/src/main/java/com/mpush/api/protocol/MPushProtocol.java @@ -42,5 +42,7 @@ public interface MPushProtocol { void unbindUser(); + void ack(int messageId); + Future sendHttp(HttpRequest request); } diff --git a/src/main/java/com/mpush/api/protocol/Packet.java b/src/main/java/com/mpush/api/protocol/Packet.java index 07c73b6..0d91b48 100644 --- a/src/main/java/com/mpush/api/protocol/Packet.java +++ b/src/main/java/com/mpush/api/protocol/Packet.java @@ -20,19 +20,21 @@ package com.mpush.api.protocol; - import java.nio.ByteBuffer; /** * Created by ohun on 2015/12/19. * * @author ohun@live.cn (夜色) - * bodyLength(4)+cmd(1)+cc(2)+flags(1)+sessionId(4)+lrc(1)+body(n) + * bodyLength(4)+cmd(1)+cc(2)+flags(1)+sessionId(4)+lrc(1)+body(n) */ public final class Packet { public static final int HEADER_LEN = 13;//packet包头协议长度 + public static final byte FLAG_CRYPTO = 0x01;//packet包启用加密 public static final byte FLAG_COMPRESS = 0x02;//packet包启用压缩 + public static final byte FLAG_BIZ_ACK = 0x04; + public static final byte FLAG_AUTO_ACK = 0x08; public static final byte HB_PACKET_BYTE = -33; public static final Packet HB_PACKET = new Packet(Command.HEARTBEAT); @@ -71,7 +73,7 @@ public void addFlag(byte flag) { } public boolean hasFlag(byte flag) { - return (flags & flag) != 0; + return (flags & flag) == flag; } public short calcCheckCode() { @@ -99,7 +101,7 @@ public byte calcLrc() { return lrc; } - public boolean vaildCheckCode() { + public boolean validCheckCode() { return calcCheckCode() == cc; } diff --git a/src/main/java/com/mpush/client/DefaultClientListener.java b/src/main/java/com/mpush/client/DefaultClientListener.java index f732fe1..643758a 100644 --- a/src/main/java/com/mpush/client/DefaultClientListener.java +++ b/src/main/java/com/mpush/client/DefaultClientListener.java @@ -75,9 +75,9 @@ public void run() { } @Override - public void onReceivePush(final Client client, final byte[] content) { + public void onReceivePush(final Client client, final byte[] content, int messageId) { if (listener != null) { - listener.onReceivePush(client, content); + listener.onReceivePush(client, content, messageId); } } diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index 335e03a..23051cc 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -29,10 +29,7 @@ import com.mpush.api.protocol.Command; import com.mpush.api.protocol.Packet; import com.mpush.handler.HttpProxyHandler; -import com.mpush.message.BindUserMessage; -import com.mpush.message.FastConnectMessage; -import com.mpush.message.HandshakeMessage; -import com.mpush.message.HttpRequestMessage; +import com.mpush.message.*; import com.mpush.security.AesCipher; import com.mpush.security.CipherBox; import com.mpush.session.PersistentSession; @@ -49,10 +46,10 @@ * * @author ohun@live.cn (夜色) */ -public final class MPushClient implements Client { - public enum State {Started, Shutdown, Destroyed} +/*package*/final class MPushClient implements Client { + private enum State {Started, Shutdown, Destroyed} - private final AtomicReference clientState = new AtomicReference(State.Shutdown); + private final AtomicReference clientState = new AtomicReference<>(State.Shutdown); private final MessageDispatcher receiver; private final TcpConnection connection; @@ -215,6 +212,15 @@ public void unbindUser() { logger.w("<<< do unbind user, userId=%s", userId); } + @Override + public void ack(int messageId) { + if (messageId > 0) { + AckMessage ackMessage = new AckMessage(messageId, connection); + ackMessage.sendRaw(); + logger.d("<<< send ack for push messageId=%d", messageId); + } + } + @Override public Future sendHttp(HttpRequest request) { if (connection.getSessionContext().handshakeOk()) { diff --git a/src/main/java/com/mpush/handler/PushMessageHandler.java b/src/main/java/com/mpush/handler/PushMessageHandler.java index bc69d22..44eaea2 100644 --- a/src/main/java/com/mpush/handler/PushMessageHandler.java +++ b/src/main/java/com/mpush/handler/PushMessageHandler.java @@ -23,6 +23,7 @@ import com.mpush.api.ClientListener; import com.mpush.api.connection.Connection; import com.mpush.api.protocol.Packet; +import com.mpush.message.AckMessage; import com.mpush.message.PushMessage; import com.mpush.client.ClientConfig; import com.mpush.api.Logger; @@ -43,7 +44,13 @@ public PushMessage decode(Packet packet, Connection connection) { @Override public void handle(PushMessage message) { - logger.d(">>> receive push messaged=%s", message.content.length); - listener.onReceivePush(message.getConnection().getClient(), message.content); + logger.d(">>> receive push message=%s", message.content.length); + listener.onReceivePush(message.getConnection().getClient(), + message.content, + message.bizAck() ? message.getSessionId() : 0); + if (message.autoAck()) { + AckMessage.from(message).sendRaw(); + logger.d("<<< send ack for push messageId=%d", message.getSessionId()); + } } } diff --git a/src/main/java/com/mpush/message/AckMessage.java b/src/main/java/com/mpush/message/AckMessage.java new file mode 100644 index 0000000..053653a --- /dev/null +++ b/src/main/java/com/mpush/message/AckMessage.java @@ -0,0 +1,46 @@ +package com.mpush.message; + +import com.mpush.api.connection.Connection; +import com.mpush.api.protocol.Command; +import com.mpush.api.protocol.Packet; +import com.mpush.util.ByteBuf; + +import java.nio.ByteBuffer; + +/** + * Created by ohun on 16/9/5. + * + * @author ohun@live.cn (夜色) + */ +public class AckMessage extends ByteBufMessage { + + public AckMessage(int sessionId, Connection connection) { + super(new Packet(Command.ACK, sessionId), connection); + } + + public AckMessage(Packet packet, Connection connection) { + super(packet, connection); + } + + @Override + protected void decode(ByteBuffer body) { + + } + + @Override + protected void encode(ByteBuf body) { + + } + + + public static AckMessage from(BaseMessage src) { + return new AckMessage(new Packet(Command.ACK, src.getSessionId()), src.connection); + } + + @Override + public String toString() { + return "AckMessage{" + + "packet=" + packet + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/com/mpush/message/PushMessage.java b/src/main/java/com/mpush/message/PushMessage.java index 58d3f28..872517c 100644 --- a/src/main/java/com/mpush/message/PushMessage.java +++ b/src/main/java/com/mpush/message/PushMessage.java @@ -47,6 +47,14 @@ public byte[] encode() { return content; } + public boolean autoAck() { + return packet.hasFlag(Packet.FLAG_AUTO_ACK); + } + + public boolean bizAck() { + return packet.hasFlag(Packet.FLAG_BIZ_ACK); + } + @Override public String toString() { return "PushMessage{" + diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 5d46ff9..10da9bf 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -48,8 +48,8 @@ public static void main(String[] args) throws Exception { .build() .setPublicKey(publicKey) //.setAllotServer(allocServer) - .setServerHost("111.1.57.148") - .setServerPort(20882) + .setServerHost("127.0.0.1") + .setServerPort(3000) .setDeviceId("1111111111") .setOsName("Android") .setOsVersion("6.0") @@ -108,8 +108,8 @@ public void run() { } @Override - public void onReceivePush(Client client, byte[] content) { - + public void onReceivePush(Client client, byte[] content, int messageId) { + if (messageId > 0) client.ack(messageId); } @Override From d23e8d67db2d26c1145e1d0d36337f24f8c47d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Tue, 6 Sep 2016 19:25:13 +0800 Subject: [PATCH 10/53] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E5=88=B00.0.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f209ee1..7587053 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.mpusher mpush-client-java - 0.0.2 + 0.0.3 jar mpush-client-java MPUSH消息推送客户端SDK From dcd93295e81997677a41a6fa840fc9f254c0d37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Mon, 19 Sep 2016 16:48:06 +0800 Subject: [PATCH 11/53] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E5=88=B00.0.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/AllotClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/mpush/client/AllotClient.java b/src/main/java/com/mpush/client/AllotClient.java index d82ffac..144db15 100644 --- a/src/main/java/com/mpush/client/AllotClient.java +++ b/src/main/java/com/mpush/client/AllotClient.java @@ -101,7 +101,7 @@ public List queryServerAddressList() { if (content.length > 0) { String result = new String(content, Constants.UTF_8); logger.w("get server address success result=%s", result); - serverAddress.addAll(Arrays.asList(result.split(","))); + serverAddress = Arrays.asList(result.split(",")); } else { logger.w("get server address failure return content empty."); } From 7359c2acb670791de6a11808b3c7f6ccab9eaa6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Mon, 19 Sep 2016 17:17:01 +0800 Subject: [PATCH 12/53] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E5=88=B00.0.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/AllotClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mpush/client/AllotClient.java b/src/main/java/com/mpush/client/AllotClient.java index 144db15..d95e57e 100644 --- a/src/main/java/com/mpush/client/AllotClient.java +++ b/src/main/java/com/mpush/client/AllotClient.java @@ -101,7 +101,9 @@ public List queryServerAddressList() { if (content.length > 0) { String result = new String(content, Constants.UTF_8); logger.w("get server address success result=%s", result); - serverAddress = Arrays.asList(result.split(",")); + for (String s : result.split(",")) { + serverAddress.add(s); + } } else { logger.w("get server address failure return content empty."); } From 5dbf9ba388b909d54c17055b5d5504eb11e4b73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Mon, 19 Sep 2016 17:27:55 +0800 Subject: [PATCH 13/53] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAllotClient=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8Bbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/AllotClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mpush/client/AllotClient.java b/src/main/java/com/mpush/client/AllotClient.java index d95e57e..90b064e 100644 --- a/src/main/java/com/mpush/client/AllotClient.java +++ b/src/main/java/com/mpush/client/AllotClient.java @@ -33,6 +33,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; /** * Created by yxx on 2016/6/8. @@ -40,7 +41,7 @@ * @author ohun@live.cn (夜色) */ /*package*/ final class AllotClient { - private List serverAddress = new ArrayList<>(); + private List serverAddress = new CopyOnWriteArrayList<>(); public List getServerAddress() { if (serverAddress.isEmpty()) { From e5582e04fe36a134bdc29c4f5b543e2fe501a5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Mon, 19 Sep 2016 17:37:00 +0800 Subject: [PATCH 14/53] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAllotClient=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8Bbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/TcpConnection.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/mpush/client/TcpConnection.java b/src/main/java/com/mpush/client/TcpConnection.java index bfb4b7d..21277f4 100644 --- a/src/main/java/com/mpush/client/TcpConnection.java +++ b/src/main/java/com/mpush/client/TcpConnection.java @@ -180,9 +180,8 @@ private boolean doReconnect() { private boolean doConnect() { List address = allotClient.getServerAddress(); if (address != null && address.size() > 0) { - Iterator it = address.iterator(); - while (it.hasNext()) { - String[] host_port = it.next().split(":"); + for (int i = 0; i < address.size(); i++) { + String[] host_port = address.get(i).split(":"); if (host_port.length == 2) { String host = host_port[0]; @@ -192,8 +191,7 @@ private boolean doConnect() { return true; } } - - it.remove(); + address.remove(i--); } } return false; From f27d30ca64bd1f51d5de1039f9724d1605d778ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Mon, 19 Sep 2016 17:43:44 +0800 Subject: [PATCH 15/53] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAllotClient=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8Bbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/AllotClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mpush/client/AllotClient.java b/src/main/java/com/mpush/client/AllotClient.java index 90b064e..7aadc48 100644 --- a/src/main/java/com/mpush/client/AllotClient.java +++ b/src/main/java/com/mpush/client/AllotClient.java @@ -41,7 +41,7 @@ * @author ohun@live.cn (夜色) */ /*package*/ final class AllotClient { - private List serverAddress = new CopyOnWriteArrayList<>(); + private List serverAddress = new ArrayList<>(); public List getServerAddress() { if (serverAddress.isEmpty()) { @@ -102,9 +102,11 @@ public List queryServerAddressList() { if (content.length > 0) { String result = new String(content, Constants.UTF_8); logger.w("get server address success result=%s", result); + List serverAddress = new ArrayList<>(); for (String s : result.split(",")) { serverAddress.add(s); } + this.serverAddress = serverAddress; } else { logger.w("get server address failure return content empty."); } From 239c692d2351c5b745d5828a86393e9cf6a6fb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 30 Sep 2016 10:51:15 +0800 Subject: [PATCH 16/53] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 12 +-- .../com/mpush/api/protocol/MPushProtocol.java | 5 + .../java/com/mpush/client/MPushClient.java | 5 +- .../com/mpush/client/MPushClientTest.java | 97 +++++++++---------- 4 files changed, 59 insertions(+), 60 deletions(-) diff --git a/.gitignore b/.gitignore index 00fd2b4..07273ce 100644 --- a/.gitignore +++ b/.gitignore @@ -5,16 +5,11 @@ */target/* */bin/* */WebContent/* -/.idea -/*.iml /*/*.iml -.idea/* -*.jar -*.war -*.ear -*.iml -./target/* +.idea/ + +target/ # Mobile Tools for Java (J2ME) .mtj.tmp/ @@ -23,6 +18,7 @@ *.jar *.war *.ear +*.iml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/src/main/java/com/mpush/api/protocol/MPushProtocol.java b/src/main/java/com/mpush/api/protocol/MPushProtocol.java index 72b32a0..0c492e4 100644 --- a/src/main/java/com/mpush/api/protocol/MPushProtocol.java +++ b/src/main/java/com/mpush/api/protocol/MPushProtocol.java @@ -32,6 +32,11 @@ */ public interface MPushProtocol { + /** + * 健康检查, 检测读写超时, 发送心跳 + * + * @return true/false Client + */ boolean healthCheck(); void fastConnect(); diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index 23051cc..1cc2761 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -186,7 +186,10 @@ public void bindUser(String userId) { return; } SessionContext context = connection.getSessionContext(); - if (userId.equals(context.bindUser)) return; + if (context.bindUser != null) { + if (userId.equals(context.bindUser)) return;//已经绑定 + else unbindUser();//切换用户,要先解绑老用户 + } context.setBindUser(userId); config.setUserId(userId); BindUserMessage diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 10da9bf..7eddb91 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -22,17 +22,9 @@ import com.mpush.api.Client; import com.mpush.api.ClientListener; -import com.mpush.api.Constants; -import com.mpush.api.http.HttpCallback; -import com.mpush.api.http.HttpMethod; -import com.mpush.api.http.HttpRequest; -import com.mpush.api.http.HttpResponse; import com.mpush.util.DefaultLogger; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.LockSupport; +import java.util.concurrent.*; /** * Created by ohun on 2016/1/25. @@ -44,33 +36,53 @@ public class MPushClientTest { private static final String allocServer = "http://127.0.0.1:9999/"; public static void main(String[] args) throws Exception { - Client client = ClientConfig - .build() - .setPublicKey(publicKey) - //.setAllotServer(allocServer) - .setServerHost("127.0.0.1") - .setServerPort(3000) - .setDeviceId("1111111111") - .setOsName("Android") - .setOsVersion("6.0") - .setClientVersion("2.0") - .setUserId("doctor43test") - .setMaxHeartbeat(10000) - .setMinHeartbeat(10000) - .setSessionStorageDir(MPushClientTest.class.getResource("/").getFile()) - .setLogger(new DefaultLogger()) - .setLogEnabled(true) - .setEnableHttpProxy(true) - .setClientListener(new L()) - .create(); - client.start(); - } + int count = 1; + String serverHost = "127.0.0.1"; + int sleep = 1000; + + if (args != null && args.length > 0) { + count = Integer.parseInt(args[0]); + if (args.length > 1) { + serverHost = args[1]; + } + if (args.length > 2) { + sleep = Integer.parseInt(args[1]); + } + } + ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(); + ClientListener listener = new L(scheduledExecutor); + for (int i = 0; i < count; i++) { + Client client = ClientConfig + .build() + .setPublicKey(publicKey) + //.setAllotServer(allocServer) + .setServerHost(serverHost) + .setServerPort(3000) + .setDeviceId("deviceId-test" + i) + .setOsName("Android") + .setOsVersion("6.0") + .setClientVersion("2.0") + .setUserId("user-" + i) + .setSessionStorageDir(MPushClientTest.class.getResource("/").getFile() + i) + .setLogger(new DefaultLogger()) + .setLogEnabled(true) + .setEnableHttpProxy(true) + .setClientListener(listener) + .create(); + client.start(); + Thread.sleep(sleep); + } + } public static class L implements ClientListener { - Thread thread; + private final ScheduledExecutorService scheduledExecutor; boolean flag = true; + public L(ScheduledExecutorService scheduledExecutor) { + this.scheduledExecutor = scheduledExecutor; + } + @Override public void onConnected(Client client) { flag = true; @@ -79,32 +91,16 @@ public void onConnected(Client client) { @Override public void onDisConnected(Client client) { flag = false; - thread.interrupt(); } @Override public void onHandshakeOk(final Client client, final int heartbeat) { - thread = new Thread(new Runnable() { + scheduledExecutor.scheduleAtFixedRate(new Runnable() { @Override public void run() { - while (flag && client.isRunning()) { - try { - Thread.sleep(heartbeat); - } catch (InterruptedException e) { - break; - } - client.healthCheck(); - /* client.stop(); - try { - Thread.sleep(3000); - } catch (InterruptedException e) { - break; - } - client.start();*/ - } + client.healthCheck(); } - }); - thread.start(); + }, heartbeat, heartbeat, TimeUnit.MILLISECONDS); } @Override @@ -116,6 +112,5 @@ public void onReceivePush(Client client, byte[] content, int messageId) { public void onKickUser(String deviceId, String userId) { } - } } \ No newline at end of file From 6e4a2886a3b0e7aa60de72af3120e5dc4735f656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 30 Sep 2016 10:59:52 +0800 Subject: [PATCH 17/53] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 101 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/pom.xml b/pom.xml index 7587053..f6f7050 100644 --- a/pom.xml +++ b/pom.xml @@ -39,20 +39,56 @@ - - - release - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2 - - - - true - - - + + release + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + @@ -73,43 +109,6 @@ true - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - - - sign-artifacts - verify - - sign - - - - From c4e143aa8da547e63c17b94133da73856a938336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 30 Sep 2016 11:15:05 +0800 Subject: [PATCH 18/53] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 131 +++++++++++++++---------- src/main/java/com/mpush/test/Main.java | 118 ++++++++++++++++++++++ 2 files changed, 199 insertions(+), 50 deletions(-) create mode 100644 src/main/java/com/mpush/test/Main.java diff --git a/pom.xml b/pom.xml index f6f7050..2baef83 100644 --- a/pom.xml +++ b/pom.xml @@ -39,56 +39,87 @@ - - release - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2 - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - - - sign-artifacts - verify - - sign - - - - - - - + + + release + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + + jar + + + + maven-jar-plugin + + + + false + + + true + + ../lib/ + + com.mpush.test.Main + + + + + + package + + + + + + + diff --git a/src/main/java/com/mpush/test/Main.java b/src/main/java/com/mpush/test/Main.java new file mode 100644 index 0000000..9f657d0 --- /dev/null +++ b/src/main/java/com/mpush/test/Main.java @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.test; + +import com.mpush.api.Client; +import com.mpush.api.ClientListener; +import com.mpush.client.ClientConfig; +import com.mpush.util.DefaultLogger; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * Created by ohun on 16/9/30. + * + * @author ohun@live.cn (夜色) + */ +public final class Main { + private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB"; + private static final String allocServer = "http://127.0.0.1:9999/"; + + public static void main(String[] args) throws Exception { + int count = 1; + String serverHost = "127.0.0.1"; + int sleep = 1000; + + if (args != null && args.length > 0) { + count = Integer.parseInt(args[0]); + if (args.length > 1) { + serverHost = args[1]; + } + if (args.length > 2) { + sleep = Integer.parseInt(args[1]); + } + } + + ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(); + ClientListener listener = new L(scheduledExecutor); + for (int i = 0; i < count; i++) { + Client client = ClientConfig + .build() + .setPublicKey(publicKey) + //.setAllotServer(allocServer) + .setServerHost(serverHost) + .setServerPort(3000) + .setDeviceId("deviceId-test" + i) + .setOsName("Android") + .setOsVersion("6.0") + .setClientVersion("2.0") + .setUserId("user-" + i) + .setSessionStorageDir("/tmp/mpush/" + i) + .setLogger(new DefaultLogger()) + .setLogEnabled(true) + .setEnableHttpProxy(true) + .setClientListener(listener) + .create(); + client.start(); + Thread.sleep(sleep); + } + } + + public static class L implements ClientListener { + private final ScheduledExecutorService scheduledExecutor; + boolean flag = true; + + public L(ScheduledExecutorService scheduledExecutor) { + this.scheduledExecutor = scheduledExecutor; + } + + @Override + public void onConnected(Client client) { + flag = true; + } + + @Override + public void onDisConnected(Client client) { + flag = false; + } + + @Override + public void onHandshakeOk(final Client client, final int heartbeat) { + scheduledExecutor.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + client.healthCheck(); + } + }, heartbeat, heartbeat, TimeUnit.MILLISECONDS); + } + + @Override + public void onReceivePush(Client client, byte[] content, int messageId) { + if (messageId > 0) client.ack(messageId); + } + + @Override + public void onKickUser(String deviceId, String userId) { + + } + } +} From ecd693b595446fe331390ec3a3bdb23cd0060ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 30 Sep 2016 11:18:33 +0800 Subject: [PATCH 19/53] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/test/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/mpush/test/Main.java b/src/main/java/com/mpush/test/Main.java index 9f657d0..70238e5 100644 --- a/src/main/java/com/mpush/test/Main.java +++ b/src/main/java/com/mpush/test/Main.java @@ -48,7 +48,7 @@ public static void main(String[] args) throws Exception { serverHost = args[1]; } if (args.length > 2) { - sleep = Integer.parseInt(args[1]); + sleep = Integer.parseInt(args[2]); } } From c53a19acd732fc22a8450df0360a97616aef70f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 30 Sep 2016 13:06:39 +0800 Subject: [PATCH 20/53] add test branch --- src/main/java/com/mpush/test/Main.java | 118 ------------------------- 1 file changed, 118 deletions(-) delete mode 100644 src/main/java/com/mpush/test/Main.java diff --git a/src/main/java/com/mpush/test/Main.java b/src/main/java/com/mpush/test/Main.java deleted file mode 100644 index 70238e5..0000000 --- a/src/main/java/com/mpush/test/Main.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * (C) Copyright 2015-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Contributors: - * ohun@live.cn (夜色) - */ - -package com.mpush.test; - -import com.mpush.api.Client; -import com.mpush.api.ClientListener; -import com.mpush.client.ClientConfig; -import com.mpush.util.DefaultLogger; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * Created by ohun on 16/9/30. - * - * @author ohun@live.cn (夜色) - */ -public final class Main { - private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB"; - private static final String allocServer = "http://127.0.0.1:9999/"; - - public static void main(String[] args) throws Exception { - int count = 1; - String serverHost = "127.0.0.1"; - int sleep = 1000; - - if (args != null && args.length > 0) { - count = Integer.parseInt(args[0]); - if (args.length > 1) { - serverHost = args[1]; - } - if (args.length > 2) { - sleep = Integer.parseInt(args[2]); - } - } - - ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(); - ClientListener listener = new L(scheduledExecutor); - for (int i = 0; i < count; i++) { - Client client = ClientConfig - .build() - .setPublicKey(publicKey) - //.setAllotServer(allocServer) - .setServerHost(serverHost) - .setServerPort(3000) - .setDeviceId("deviceId-test" + i) - .setOsName("Android") - .setOsVersion("6.0") - .setClientVersion("2.0") - .setUserId("user-" + i) - .setSessionStorageDir("/tmp/mpush/" + i) - .setLogger(new DefaultLogger()) - .setLogEnabled(true) - .setEnableHttpProxy(true) - .setClientListener(listener) - .create(); - client.start(); - Thread.sleep(sleep); - } - } - - public static class L implements ClientListener { - private final ScheduledExecutorService scheduledExecutor; - boolean flag = true; - - public L(ScheduledExecutorService scheduledExecutor) { - this.scheduledExecutor = scheduledExecutor; - } - - @Override - public void onConnected(Client client) { - flag = true; - } - - @Override - public void onDisConnected(Client client) { - flag = false; - } - - @Override - public void onHandshakeOk(final Client client, final int heartbeat) { - scheduledExecutor.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - client.healthCheck(); - } - }, heartbeat, heartbeat, TimeUnit.MILLISECONDS); - } - - @Override - public void onReceivePush(Client client, byte[] content, int messageId) { - if (messageId > 0) client.ack(messageId); - } - - @Override - public void onKickUser(String deviceId, String userId) { - - } - } -} From 3dd4b85610d9082468e7af0f4595eeab4fb525f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Thu, 13 Oct 2016 22:02:10 +0800 Subject: [PATCH 21/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0push=20=E4=B8=8A?= =?UTF-8?q?=E8=A1=8C=E6=96=B9=E6=B3=95client->server?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mpush/api/protocol/MPushProtocol.java | 4 + .../java/com/mpush/api/push/AckModel.java | 38 ++++++ .../java/com/mpush/api/push/PushCallback.java | 32 +++++ .../java/com/mpush/api/push/PushContext.java | 82 +++++++++++++ .../java/com/mpush/api/push/PushResult.java | 28 +++++ .../com/mpush/client/AckMessageQueue.java | 114 ++++++++++++++++++ .../java/com/mpush/client/ClientConfig.java | 10 ++ .../java/com/mpush/client/MPushClient.java | 28 ++++- .../java/com/mpush/handler/AckHandler.java | 59 +++++++++ .../java/com/mpush/message/PushMessage.java | 11 ++ .../com/mpush/client/MPushClientTest.java | 9 +- 11 files changed, 410 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/mpush/api/push/AckModel.java create mode 100644 src/main/java/com/mpush/api/push/PushCallback.java create mode 100644 src/main/java/com/mpush/api/push/PushContext.java create mode 100644 src/main/java/com/mpush/api/push/PushResult.java create mode 100644 src/main/java/com/mpush/client/AckMessageQueue.java create mode 100644 src/main/java/com/mpush/handler/AckHandler.java diff --git a/src/main/java/com/mpush/api/protocol/MPushProtocol.java b/src/main/java/com/mpush/api/protocol/MPushProtocol.java index 0c492e4..881dda6 100644 --- a/src/main/java/com/mpush/api/protocol/MPushProtocol.java +++ b/src/main/java/com/mpush/api/protocol/MPushProtocol.java @@ -22,6 +22,8 @@ import com.mpush.api.http.HttpRequest; import com.mpush.api.http.HttpResponse; +import com.mpush.api.push.AckModel; +import com.mpush.api.push.PushContext; import java.util.concurrent.Future; @@ -49,5 +51,7 @@ public interface MPushProtocol { void ack(int messageId); + Future push(PushContext context); + Future sendHttp(HttpRequest request); } diff --git a/src/main/java/com/mpush/api/push/AckModel.java b/src/main/java/com/mpush/api/push/AckModel.java new file mode 100644 index 0000000..aff9843 --- /dev/null +++ b/src/main/java/com/mpush/api/push/AckModel.java @@ -0,0 +1,38 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api.push; + +import com.mpush.api.protocol.Packet; + +/** + * Created by ohun on 16/9/6. + * + * @author ohun@live.cn (夜色) + */ +public enum AckModel { + NO_ACK((byte) 0),//不需要ACK + AUTO_ACK(Packet.FLAG_AUTO_ACK),//客户端收到消息后自动确认消息 + BIZ_ACK(Packet.FLAG_BIZ_ACK);//由客户端业务自己确认消息是否到达 + public final byte flag; + + AckModel(byte flag) { + this.flag = flag; + } +} diff --git a/src/main/java/com/mpush/api/push/PushCallback.java b/src/main/java/com/mpush/api/push/PushCallback.java new file mode 100644 index 0000000..8c9bb87 --- /dev/null +++ b/src/main/java/com/mpush/api/push/PushCallback.java @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api.push; + +/** + * Created by ohun on 16/10/13. + * + * @author ohun@live.cn (夜色) + */ +public interface PushCallback { + + void onSuccess(); + + void onTimeout(); +} diff --git a/src/main/java/com/mpush/api/push/PushContext.java b/src/main/java/com/mpush/api/push/PushContext.java new file mode 100644 index 0000000..503d530 --- /dev/null +++ b/src/main/java/com/mpush/api/push/PushContext.java @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api.push; + +import com.mpush.api.Constants; + +/** + * Created by ohun on 16/10/13. + * + * @author ohun@live.cn (夜色) + */ +public final class PushContext { + public byte[] content; + public AckModel ackModel = AckModel.NO_ACK; + public PushCallback callback; + public int timeout = 1000; + + public PushContext(byte[] content) { + this.content = content; + } + + public static PushContext build(byte[] content) { + return new PushContext(content); + } + + public static PushContext build(String content) { + return new PushContext(content.getBytes(Constants.UTF_8)); + } + + public byte[] getContent() { + return content; + } + + public PushContext setContent(byte[] content) { + this.content = content; + return this; + } + + public AckModel getAckModel() { + return ackModel; + } + + public PushContext setAckModel(AckModel ackModel) { + this.ackModel = ackModel; + return this; + } + + public PushCallback getCallback() { + return callback; + } + + public PushContext setCallback(PushCallback callback) { + this.callback = callback; + return this; + } + + public int getTimeout() { + return timeout; + } + + public PushContext setTimeout(int timeout) { + this.timeout = timeout; + return this; + } +} diff --git a/src/main/java/com/mpush/api/push/PushResult.java b/src/main/java/com/mpush/api/push/PushResult.java new file mode 100644 index 0000000..01e255f --- /dev/null +++ b/src/main/java/com/mpush/api/push/PushResult.java @@ -0,0 +1,28 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api.push; + +/** + * Created by ohun on 16/10/13. + * + * @author ohun@live.cn (夜色) + */ +public final class PushResult { +} diff --git a/src/main/java/com/mpush/client/AckMessageQueue.java b/src/main/java/com/mpush/client/AckMessageQueue.java new file mode 100644 index 0000000..7f77545 --- /dev/null +++ b/src/main/java/com/mpush/client/AckMessageQueue.java @@ -0,0 +1,114 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.client; + + +import com.mpush.api.Logger; +import com.mpush.api.http.HttpCallback; +import com.mpush.api.http.HttpRequest; +import com.mpush.api.http.HttpResponse; +import com.mpush.api.push.AckModel; +import com.mpush.api.push.PushCallback; +import com.mpush.api.push.PushContext; +import com.mpush.util.thread.ExecutorManager; + +import java.util.Map; +import java.util.concurrent.*; + +import static java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT; + +/** + * Created by yxx on 2016/2/16. + * + * @author ohun@live.cn + */ +public final class AckMessageQueue { + private final Map queue = new ConcurrentHashMap<>(); + private final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getHttpRequestThread(); + private final Callable NONE = new Callable() { + @Override + public Boolean call() throws Exception { + return Boolean.FALSE; + } + }; + + private final Logger logger = ClientConfig.I.getLogger(); + + public Future add(int sessionId, PushContext context) { + if (context.ackModel == AckModel.NO_ACK) return null; + if (context.callback == null) return null; + PushTask task = new PushTask(sessionId, context); + queue.put(sessionId, task); + task.future = timer.schedule(task, task.timeout, TimeUnit.MILLISECONDS); + return task; + } + + public PushTask getAndRemove(int sessionId) { + return queue.remove(sessionId); + } + + public final class PushTask extends FutureTask implements Runnable { + private PushCallback callback; + private final int timeout; + private final long sendTime; + private final int sessionId; + private Future future; + + private PushTask(int sessionId, PushContext context) { + super(NONE); + this.callback = context.getCallback(); + this.timeout = context.getTimeout(); + this.sendTime = System.currentTimeMillis(); + this.sessionId = sessionId; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + throw new UnsupportedOperationException(); + } + + @Override + public void run() { + queue.remove(sessionId); + timeout(); + } + + public void timeout() { + call(false); + } + + public void success() { + call(true); + } + + private void call(boolean success) { + if (this.future.cancel(true)) { + this.set(success); + if (callback != null) { + if (success) callback.onSuccess(); + else callback.onTimeout(); + } + callback = null; + } + logger.d("one push task end, sessionId=%d, costTime=%d, success=%b", + sessionId, (System.currentTimeMillis() - sendTime), success); + } + } +} diff --git a/src/main/java/com/mpush/client/ClientConfig.java b/src/main/java/com/mpush/client/ClientConfig.java index dbd4a1a..82ef59f 100644 --- a/src/main/java/com/mpush/client/ClientConfig.java +++ b/src/main/java/com/mpush/client/ClientConfig.java @@ -54,6 +54,7 @@ public final class ClientConfig { private Logger logger; private boolean logEnabled; private boolean enableHttpProxy = true; + private boolean enableClientPush = true; public static ClientConfig build() { return I = new ClientConfig(); @@ -246,4 +247,13 @@ public ClientConfig setServerPort(int serverPort) { this.serverPort = serverPort; return this; } + + public boolean isEnableClientPush() { + return enableClientPush; + } + + public ClientConfig setEnableClientPush(boolean enableClientPush) { + this.enableClientPush = enableClientPush; + return this; + } } diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index 1cc2761..002631e 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -28,6 +28,8 @@ import com.mpush.api.http.HttpResponse; import com.mpush.api.protocol.Command; import com.mpush.api.protocol.Packet; +import com.mpush.api.push.PushContext; +import com.mpush.handler.AckHandler; import com.mpush.handler.HttpProxyHandler; import com.mpush.message.*; import com.mpush.security.AesCipher; @@ -57,7 +59,8 @@ private enum State {Started, Shutdown, Destroyed} private final Logger logger; private int hbTimeoutTimes; - private HttpRequestQueue requestQueue; + private HttpRequestQueue httpRequestQueue; + private AckMessageQueue ackMessageQueue; /*package*/ MPushClient(ClientConfig config) { this.config = config; @@ -65,8 +68,13 @@ private enum State {Started, Shutdown, Destroyed} this.receiver = new MessageDispatcher(); this.connection = new TcpConnection(this, receiver); if (config.isEnableHttpProxy()) { - this.requestQueue = new HttpRequestQueue(); - this.receiver.register(Command.HTTP_PROXY, new HttpProxyHandler(requestQueue)); + this.httpRequestQueue = new HttpRequestQueue(); + this.receiver.register(Command.HTTP_PROXY, new HttpProxyHandler(httpRequestQueue)); + } + + if (config.isEnableClientPush()) { + this.ackMessageQueue = new AckMessageQueue(); + this.receiver.register(Command.ACK, new AckHandler(ackMessageQueue)); } } @@ -224,6 +232,18 @@ public void ack(int messageId) { } } + @Override + public Future push(PushContext context) { + if (connection.getSessionContext().handshakeOk()) { + PushMessage message = new PushMessage(context.content, connection); + message.addFlag(context.ackModel.flag); + message.send(); + logger.d("<<< send push message=%s", message); + return ackMessageQueue.add(message.getSessionId(), context); + } + return null; + } + @Override public Future sendHttp(HttpRequest request) { if (connection.getSessionContext().handshakeOk()) { @@ -234,7 +254,7 @@ public Future sendHttp(HttpRequest request) { message.body = request.getBody(); message.send(); logger.d("<<< send http proxy, request=%s", request); - return requestQueue.add(message.getSessionId(), request); + return httpRequestQueue.add(message.getSessionId(), request); } return null; } diff --git a/src/main/java/com/mpush/handler/AckHandler.java b/src/main/java/com/mpush/handler/AckHandler.java new file mode 100644 index 0000000..8f107ca --- /dev/null +++ b/src/main/java/com/mpush/handler/AckHandler.java @@ -0,0 +1,59 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.handler; + +import com.mpush.api.Logger; +import com.mpush.api.connection.Connection; +import com.mpush.api.protocol.Packet; +import com.mpush.client.AckMessageQueue; +import com.mpush.client.ClientConfig; +import com.mpush.message.AckMessage; + +/** + * Created by ohun on 16/9/5. + * + * @author ohun@live.cn (夜色) + */ +public class AckHandler extends BaseMessageHandler { + + private AckMessageQueue ackMessageQueue; + + private Logger logger; + + public AckHandler(AckMessageQueue ackMessageQueue) { + this.ackMessageQueue = ackMessageQueue; + this.logger = ClientConfig.I.getLogger(); + } + + @Override + public AckMessage decode(Packet packet, Connection connection) { + return new AckMessage(packet, connection); + } + + @Override + public void handle(AckMessage message) { + AckMessageQueue.PushTask task = ackMessageQueue.getAndRemove(message.getSessionId()); + if (task == null) { + logger.w("receive server ack, but timeout message={}", message); + return; + } + task.success(); + } +} diff --git a/src/main/java/com/mpush/message/PushMessage.java b/src/main/java/com/mpush/message/PushMessage.java index 872517c..f4b84db 100644 --- a/src/main/java/com/mpush/message/PushMessage.java +++ b/src/main/java/com/mpush/message/PushMessage.java @@ -21,6 +21,7 @@ import com.mpush.api.connection.Connection; +import com.mpush.api.protocol.Command; import com.mpush.api.protocol.Packet; import com.mpush.api.Constants; @@ -33,6 +34,11 @@ public final class PushMessage extends BaseMessage { public byte[] content; + public PushMessage(byte[] content, Connection connection) { + super(new Packet(Command.PUSH, genSessionId()), connection); + this.content = content; + } + public PushMessage(Packet packet, Connection connection) { super(packet, connection); } @@ -55,6 +61,11 @@ public boolean bizAck() { return packet.hasFlag(Packet.FLAG_BIZ_ACK); } + public PushMessage addFlag(byte flag) { + packet.addFlag(flag); + return this; + } + @Override public String toString() { return "PushMessage{" + diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 7eddb91..4982bd5 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -22,6 +22,9 @@ import com.mpush.api.Client; import com.mpush.api.ClientListener; +import com.mpush.api.push.AckModel; +import com.mpush.api.push.PushCallback; +import com.mpush.api.push.PushContext; import com.mpush.util.DefaultLogger; import java.util.concurrent.*; @@ -52,8 +55,9 @@ public static void main(String[] args) throws Exception { ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(); ClientListener listener = new L(scheduledExecutor); + Client client = null; for (int i = 0; i < count; i++) { - Client client = ClientConfig + client = ClientConfig .build() .setPublicKey(publicKey) //.setAllotServer(allocServer) @@ -101,6 +105,9 @@ public void run() { client.healthCheck(); } }, heartbeat, heartbeat, TimeUnit.MILLISECONDS); + + client.push(PushContext.build("test")); + } @Override From 0ecf919da3a73f0a85756b956c3280afa70fe2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sat, 15 Oct 2016 13:05:02 +0800 Subject: [PATCH 22/53] =?UTF-8?q?=E6=96=AD=E7=BA=BF=E5=90=8E=E5=85=88?= =?UTF-8?q?=E4=B8=8D=E8=A6=81=E7=AB=8B=E5=8D=B3=E9=87=8D=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/codec/AsyncPacketReader.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/mpush/codec/AsyncPacketReader.java b/src/main/java/com/mpush/codec/AsyncPacketReader.java index cf6cace..07088a2 100644 --- a/src/main/java/com/mpush/codec/AsyncPacketReader.java +++ b/src/main/java/com/mpush/codec/AsyncPacketReader.java @@ -101,7 +101,15 @@ private boolean read(SocketChannel channel, ByteBuffer in) { } catch (IOException e) { logger.e(e, "read packet ex, do reconnect"); readCount = -1; + sleep4Reconnect(); } return readCount > 0; } + + private void sleep4Reconnect() { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + } + } } From cabdb0b9c37fb33a376d1378c7b063d557f9b522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sat, 15 Oct 2016 13:05:28 +0800 Subject: [PATCH 23/53] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/com/mpush/client/MPushClientTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 4982bd5..7e177db 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -29,6 +29,8 @@ import java.util.concurrent.*; +import static com.apple.eio.FileManager.getResource; + /** * Created by ohun on 2016/1/25. * @@ -56,6 +58,7 @@ public static void main(String[] args) throws Exception { ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(); ClientListener listener = new L(scheduledExecutor); Client client = null; + String cacheDir = MPushClientTest.class.getResource("/").getFile(); for (int i = 0; i < count; i++) { client = ClientConfig .build() @@ -68,7 +71,7 @@ public static void main(String[] args) throws Exception { .setOsVersion("6.0") .setClientVersion("2.0") .setUserId("user-" + i) - .setSessionStorageDir(MPushClientTest.class.getResource("/").getFile() + i) + .setSessionStorageDir(cacheDir + i) .setLogger(new DefaultLogger()) .setLogEnabled(true) .setEnableHttpProxy(true) From 15a5050fad65a1eefd672c78a9bcba45349d4abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sat, 15 Oct 2016 16:42:16 +0800 Subject: [PATCH 24/53] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0v0.0.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- src/test/java/com/mpush/client/MPushClientTest.java | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 2baef83..5537064 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.mpusher mpush-client-java - 0.0.3 + 0.0.5 jar mpush-client-java MPUSH消息推送客户端SDK diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 7e177db..00e2ef2 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -22,14 +22,12 @@ import com.mpush.api.Client; import com.mpush.api.ClientListener; -import com.mpush.api.push.AckModel; -import com.mpush.api.push.PushCallback; import com.mpush.api.push.PushContext; import com.mpush.util.DefaultLogger; -import java.util.concurrent.*; - -import static com.apple.eio.FileManager.getResource; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; /** * Created by ohun on 2016/1/25. From 86dc8d4e8452064431f314db3bab3d2ebb4995d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Tue, 18 Oct 2016 19:57:20 +0800 Subject: [PATCH 25/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0bind=20tags=20=E5=92=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9tags=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/api/BindCallback.java | 29 +++++++++++++++++ .../java/com/mpush/api/ClientListener.java | 4 +++ .../mpush/api/connection/SessionContext.java | 9 +++++- .../com/mpush/api/protocol/MPushProtocol.java | 3 +- .../java/com/mpush/client/ClientConfig.java | 10 ++++++ .../mpush/client/DefaultClientListener.java | 31 ++++++++++++------- .../java/com/mpush/client/MPushClient.java | 20 +++++++----- .../com/mpush/handler/OkMessageHandler.java | 8 ++++- .../com/mpush/client/MPushClientTest.java | 11 +++++++ 9 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/mpush/api/BindCallback.java diff --git a/src/main/java/com/mpush/api/BindCallback.java b/src/main/java/com/mpush/api/BindCallback.java new file mode 100644 index 0000000..51da223 --- /dev/null +++ b/src/main/java/com/mpush/api/BindCallback.java @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api; + +/** + * Created by ohun on 16/10/17. + * + * @author ohun@live.cn (夜色) + */ +public interface BindCallback { + +} diff --git a/src/main/java/com/mpush/api/ClientListener.java b/src/main/java/com/mpush/api/ClientListener.java index 4773ec3..719d1ac 100644 --- a/src/main/java/com/mpush/api/ClientListener.java +++ b/src/main/java/com/mpush/api/ClientListener.java @@ -36,4 +36,8 @@ public interface ClientListener { void onReceivePush(Client client, byte[] content, int messageId); void onKickUser(String deviceId, String userId); + + void onBind(boolean success, String userId); + + void onUnbind(boolean success, String userId); } diff --git a/src/main/java/com/mpush/api/connection/SessionContext.java b/src/main/java/com/mpush/api/connection/SessionContext.java index 9902a5c..f47ba38 100644 --- a/src/main/java/com/mpush/api/connection/SessionContext.java +++ b/src/main/java/com/mpush/api/connection/SessionContext.java @@ -29,6 +29,7 @@ public final class SessionContext { public int heartbeat; public Cipher cipher; public String bindUser; + public String tags; public void changeCipher(Cipher cipher) { this.cipher = cipher; @@ -38,8 +39,14 @@ public void setHeartbeat(int heartbeat) { this.heartbeat = heartbeat; } - public void setBindUser(String bindUser) { + public SessionContext setBindUser(String bindUser) { this.bindUser = bindUser; + return this; + } + + public SessionContext setTags(String tags) { + this.tags = tags; + return this; } public boolean handshakeOk() { diff --git a/src/main/java/com/mpush/api/protocol/MPushProtocol.java b/src/main/java/com/mpush/api/protocol/MPushProtocol.java index 881dda6..9622ec3 100644 --- a/src/main/java/com/mpush/api/protocol/MPushProtocol.java +++ b/src/main/java/com/mpush/api/protocol/MPushProtocol.java @@ -22,7 +22,6 @@ import com.mpush.api.http.HttpRequest; import com.mpush.api.http.HttpResponse; -import com.mpush.api.push.AckModel; import com.mpush.api.push.PushContext; import java.util.concurrent.Future; @@ -45,7 +44,7 @@ public interface MPushProtocol { void handshake(); - void bindUser(String userId); + void bindUser(String userId, String tags); void unbindUser(); diff --git a/src/main/java/com/mpush/client/ClientConfig.java b/src/main/java/com/mpush/client/ClientConfig.java index 82ef59f..58e3cd6 100644 --- a/src/main/java/com/mpush/client/ClientConfig.java +++ b/src/main/java/com/mpush/client/ClientConfig.java @@ -45,6 +45,7 @@ public final class ClientConfig { private String osVersion; private String clientVersion; private String userId; + private String tags; private int maxHeartbeat = Constants.DEF_HEARTBEAT; private int minHeartbeat = Constants.DEF_HEARTBEAT; private int aesKeyLength = 16; @@ -256,4 +257,13 @@ public ClientConfig setEnableClientPush(boolean enableClientPush) { this.enableClientPush = enableClientPush; return this; } + + public String getTags() { + return tags; + } + + public ClientConfig setTags(String tags) { + this.tags = tags; + return this; + } } diff --git a/src/main/java/com/mpush/client/DefaultClientListener.java b/src/main/java/com/mpush/client/DefaultClientListener.java index 643758a..e51954d 100644 --- a/src/main/java/com/mpush/client/DefaultClientListener.java +++ b/src/main/java/com/mpush/client/DefaultClientListener.java @@ -61,30 +61,37 @@ public void run() { @Override public void onHandshakeOk(final Client client, final int heartbeat) { - if (listener != null) { - executor.execute(new Runnable() { - @Override - public void run() { - listener.onHandshakeOk(client, heartbeat); - } - }); - } else { - //do heathCheck + if (listener != null) {//dispatcher已经使用了Executor,此处直接同步调用 + listener.onHandshakeOk(client, heartbeat); } - client.bindUser(ClientConfig.I.getUserId()); + client.bindUser(ClientConfig.I.getUserId(), ClientConfig.I.getTags()); } @Override public void onReceivePush(final Client client, final byte[] content, int messageId) { - if (listener != null) { + if (listener != null) {//dispatcher已经使用了Executor,此处直接同步调用 listener.onReceivePush(client, content, messageId); } } @Override public void onKickUser(String deviceId, String userId) { - if (listener != null) { + if (listener != null) {//dispatcher已经使用了Executor,此处直接同步调用 listener.onKickUser(deviceId, userId); } } + + @Override + public void onBind(boolean success, String userId) { + if (listener != null) {//dispatcher已经使用了Executor,此处直接同步调用 + listener.onBind(success, userId); + } + } + + @Override + public void onUnbind(boolean success, String userId) { + if (listener != null) {//dispatcher已经使用了Executor,此处直接同步调用 + listener.onUnbind(success, userId); + } + } } \ No newline at end of file diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index 002631e..ff11bf2 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -41,7 +41,7 @@ import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; -import static com.mpush.api.Constants.*; +import static com.mpush.api.Constants.MAX_HB_TIMEOUT_COUNT; /** * Created by ohun on 2016/1/17. @@ -188,21 +188,25 @@ public void handshake() { } @Override - public void bindUser(String userId) { + public void bindUser(String userId, String tags) { if (Strings.isBlank(userId)) { logger.w("bind user is null"); return; } SessionContext context = connection.getSessionContext(); if (context.bindUser != null) { - if (userId.equals(context.bindUser)) return;//已经绑定 - else unbindUser();//切换用户,要先解绑老用户 + if (userId.equals(context.bindUser)) {//已经绑定 + if (tags != null && tags.equals(context.tags)) return; + } else { + unbindUser();//切换用户,要先解绑老用户 + } } - context.setBindUser(userId); - config.setUserId(userId); + context.setBindUser(userId).setTags(tags); + config.setUserId(userId).setTags(tags); BindUserMessage .buildBind(connection) .setUserId(userId) + .setTags(tags) .send(); logger.w("<<< do bind user, userId=%s", userId); } @@ -214,8 +218,8 @@ public void unbindUser() { logger.w("unbind user is null"); return; } - config.setUserId(null); - connection.getSessionContext().setBindUser(null); + config.setUserId(null).setTags(null); + connection.getSessionContext().setBindUser(null).setTags(null); BindUserMessage .buildUnbind(connection) .setUserId(userId) diff --git a/src/main/java/com/mpush/handler/OkMessageHandler.java b/src/main/java/com/mpush/handler/OkMessageHandler.java index 8ef2910..30ecc99 100644 --- a/src/main/java/com/mpush/handler/OkMessageHandler.java +++ b/src/main/java/com/mpush/handler/OkMessageHandler.java @@ -20,8 +20,8 @@ package com.mpush.handler; - import com.mpush.api.connection.Connection; +import com.mpush.api.protocol.Command; import com.mpush.api.protocol.Packet; import com.mpush.message.OkMessage; import com.mpush.api.Logger; @@ -42,6 +42,12 @@ public OkMessage decode(Packet packet, Connection connection) { @Override public void handle(OkMessage message) { + if (message.cmd == Command.BIND.cmd) { + ClientConfig.I.getClientListener().onBind(true, message.getConnection().getSessionContext().bindUser); + } else if (message.cmd == Command.UNBIND.cmd) { + ClientConfig.I.getClientListener().onUnbind(true, null); + } + logger.w(">>> receive ok message=%s", message); } } diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 00e2ef2..ae27c1c 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -69,6 +69,7 @@ public static void main(String[] args) throws Exception { .setOsVersion("6.0") .setClientVersion("2.0") .setUserId("user-" + i) + .setTags("tag-" + i) .setSessionStorageDir(cacheDir + i) .setLogger(new DefaultLogger()) .setLogEnabled(true) @@ -120,5 +121,15 @@ public void onReceivePush(Client client, byte[] content, int messageId) { public void onKickUser(String deviceId, String userId) { } + + @Override + public void onBind(boolean success, String userId) { + + } + + @Override + public void onUnbind(boolean success, String userId) { + + } } } \ No newline at end of file From 0e21da47d8072d9cdabe89da09460f5924bdd9cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 21:57:36 +0800 Subject: [PATCH 26/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AFACK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/message/FastConnectMessage.java | 4 ++-- src/main/java/com/mpush/message/FastConnectOkMessage.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/mpush/message/FastConnectMessage.java b/src/main/java/com/mpush/message/FastConnectMessage.java index e831818..fad79f5 100644 --- a/src/main/java/com/mpush/message/FastConnectMessage.java +++ b/src/main/java/com/mpush/message/FastConnectMessage.java @@ -20,7 +20,6 @@ package com.mpush.message; - import com.mpush.api.connection.Connection; import com.mpush.api.protocol.Command; import com.mpush.api.protocol.Packet; @@ -66,7 +65,8 @@ public void encode(ByteBuf body) { @Override public String toString() { return "FastConnectMessage{" + - "sessionId='" + sessionId + '\'' + + "sessionId=" + packet.sessionId + + ", sessionId='" + sessionId + '\'' + ", deviceId='" + deviceId + '\'' + ", minHeartbeat=" + minHeartbeat + ", maxHeartbeat=" + maxHeartbeat + diff --git a/src/main/java/com/mpush/message/FastConnectOkMessage.java b/src/main/java/com/mpush/message/FastConnectOkMessage.java index d81b5a6..a84c197 100644 --- a/src/main/java/com/mpush/message/FastConnectOkMessage.java +++ b/src/main/java/com/mpush/message/FastConnectOkMessage.java @@ -20,7 +20,6 @@ package com.mpush.message; - import com.mpush.api.connection.Connection; import com.mpush.api.protocol.Packet; import com.mpush.util.ByteBuf; @@ -61,7 +60,8 @@ public FastConnectOkMessage setHeartbeat(int heartbeat) { @Override public String toString() { return "FastConnectOkMessage{" + - "heartbeat=" + heartbeat + + "sessionId=" + packet.sessionId + + ", heartbeat=" + heartbeat + '}'; } } From a6a85628e1cb3a24ace3d4cb611d3eea86bd2b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 21:57:56 +0800 Subject: [PATCH 27/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AFACK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/message/HandshakeMessage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mpush/message/HandshakeMessage.java b/src/main/java/com/mpush/message/HandshakeMessage.java index 27ed9b2..233d1fe 100644 --- a/src/main/java/com/mpush/message/HandshakeMessage.java +++ b/src/main/java/com/mpush/message/HandshakeMessage.java @@ -20,7 +20,6 @@ package com.mpush.message; - import com.mpush.api.connection.Connection; import com.mpush.api.protocol.Command; import com.mpush.api.protocol.Packet; @@ -82,7 +81,8 @@ protected void encode(ByteBuf body) { @Override public String toString() { return "HandshakeMessage{" + - "deviceId='" + deviceId + '\'' + + "sessionId=" + packet.sessionId + + ", deviceId='" + deviceId + '\'' + ", osName='" + osName + '\'' + ", osVersion='" + osVersion + '\'' + ", clientVersion='" + clientVersion + '\'' + From 2e1c78f9072348ffa5f42abfdfc47586ace02cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 21:58:23 +0800 Subject: [PATCH 28/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AFACK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/com/mpush/client/MPushClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index ae27c1c..a337dce 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -108,7 +108,7 @@ public void run() { } }, heartbeat, heartbeat, TimeUnit.MILLISECONDS); - client.push(PushContext.build("test")); + //client.push(PushContext.build("test")); } From d4d65bb2ddb1a563cecce8cb9b80af7344c2c502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 21:59:16 +0800 Subject: [PATCH 29/53] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/TcpConnection.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/mpush/client/TcpConnection.java b/src/main/java/com/mpush/client/TcpConnection.java index 21277f4..724996e 100644 --- a/src/main/java/com/mpush/client/TcpConnection.java +++ b/src/main/java/com/mpush/client/TcpConnection.java @@ -52,9 +52,8 @@ public final class TcpConnection implements Connection { public enum State {connecting, connected, disconnecting, disconnected} - private final AtomicReference state = new AtomicReference(disconnected); + private final AtomicReference state = new AtomicReference<>(disconnected); private final EventLock connLock = new EventLock(); - private final ClientConfig config; private final Logger logger; private final ClientListener listener; private final MPushClient client; @@ -71,8 +70,8 @@ public enum State {connecting, connected, disconnecting, disconnected} private volatile boolean autoConnect = true; public TcpConnection(MPushClient client, PacketReceiver receiver) { + ClientConfig config = ClientConfig.I; this.client = client; - this.config = ClientConfig.I; this.logger = config.getLogger(); this.listener = config.getClientListener(); this.allotClient = new AllotClient(); From 6aabda7912bda6bc263249fb24b05894727f2f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 21:59:51 +0800 Subject: [PATCH 30/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AFACK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mpush/api/ack/AckCallback.java | 33 ++++ .../java/com/mpush/api/ack/AckContext.java | 86 +++++++++ .../com/mpush/api/{push => ack}/AckModel.java | 2 +- .../com/mpush/client/AckMessageQueue.java | 114 ------------ .../java/com/mpush/client/AckRequestMgr.java | 171 ++++++++++++++++++ .../java/com/mpush/handler/AckHandler.java | 19 +- 6 files changed, 299 insertions(+), 126 deletions(-) create mode 100644 src/main/java/com/mpush/api/ack/AckCallback.java create mode 100644 src/main/java/com/mpush/api/ack/AckContext.java rename src/main/java/com/mpush/api/{push => ack}/AckModel.java (97%) delete mode 100644 src/main/java/com/mpush/client/AckMessageQueue.java create mode 100644 src/main/java/com/mpush/client/AckRequestMgr.java diff --git a/src/main/java/com/mpush/api/ack/AckCallback.java b/src/main/java/com/mpush/api/ack/AckCallback.java new file mode 100644 index 0000000..37bcdbe --- /dev/null +++ b/src/main/java/com/mpush/api/ack/AckCallback.java @@ -0,0 +1,33 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api.ack; + +import com.mpush.api.protocol.Packet; + +/** + * Created by ohun on 2016/11/13. + * + * @author ohun@live.cn (夜色) + */ +public interface AckCallback { + void onSuccess(Packet response); + + void onTimeout(Packet request); +} diff --git a/src/main/java/com/mpush/api/ack/AckContext.java b/src/main/java/com/mpush/api/ack/AckContext.java new file mode 100644 index 0000000..cc064e0 --- /dev/null +++ b/src/main/java/com/mpush/api/ack/AckContext.java @@ -0,0 +1,86 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api.ack; + +import com.mpush.api.protocol.Packet; + +/** + * Created by ohun on 2016/11/13. + * + * @author ohun@live.cn (夜色) + */ +public class AckContext { + public AckCallback callback; + public AckModel ackModel = AckModel.AUTO_ACK; + public int timeout = 1000; + public Packet request; + public int retryCount = 1; + + public static AckContext build(AckCallback callback) { + AckContext context = new AckContext(); + context.setCallback(callback); + return context; + } + + public AckCallback getCallback() { + return callback; + } + + public AckContext setCallback(AckCallback callback) { + this.callback = callback; + return this; + } + + public AckModel getAckModel() { + return ackModel; + } + + public AckContext setAckModel(AckModel ackModel) { + this.ackModel = ackModel; + return this; + } + + public int getTimeout() { + return timeout; + } + + public AckContext setTimeout(int timeout) { + this.timeout = timeout; + return this; + } + + public Packet getRequest() { + return request; + } + + public AckContext setRequest(Packet request) { + this.request = request; + return this; + } + + public int getRetryCount() { + return retryCount; + } + + public AckContext setRetryCount(int retryCount) { + this.retryCount = retryCount; + return this; + } +} diff --git a/src/main/java/com/mpush/api/push/AckModel.java b/src/main/java/com/mpush/api/ack/AckModel.java similarity index 97% rename from src/main/java/com/mpush/api/push/AckModel.java rename to src/main/java/com/mpush/api/ack/AckModel.java index aff9843..42fa6bc 100644 --- a/src/main/java/com/mpush/api/push/AckModel.java +++ b/src/main/java/com/mpush/api/ack/AckModel.java @@ -17,7 +17,7 @@ * ohun@live.cn (夜色) */ -package com.mpush.api.push; +package com.mpush.api.ack; import com.mpush.api.protocol.Packet; diff --git a/src/main/java/com/mpush/client/AckMessageQueue.java b/src/main/java/com/mpush/client/AckMessageQueue.java deleted file mode 100644 index 7f77545..0000000 --- a/src/main/java/com/mpush/client/AckMessageQueue.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * (C) Copyright 2015-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Contributors: - * ohun@live.cn (夜色) - */ - -package com.mpush.client; - - -import com.mpush.api.Logger; -import com.mpush.api.http.HttpCallback; -import com.mpush.api.http.HttpRequest; -import com.mpush.api.http.HttpResponse; -import com.mpush.api.push.AckModel; -import com.mpush.api.push.PushCallback; -import com.mpush.api.push.PushContext; -import com.mpush.util.thread.ExecutorManager; - -import java.util.Map; -import java.util.concurrent.*; - -import static java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT; - -/** - * Created by yxx on 2016/2/16. - * - * @author ohun@live.cn - */ -public final class AckMessageQueue { - private final Map queue = new ConcurrentHashMap<>(); - private final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getHttpRequestThread(); - private final Callable NONE = new Callable() { - @Override - public Boolean call() throws Exception { - return Boolean.FALSE; - } - }; - - private final Logger logger = ClientConfig.I.getLogger(); - - public Future add(int sessionId, PushContext context) { - if (context.ackModel == AckModel.NO_ACK) return null; - if (context.callback == null) return null; - PushTask task = new PushTask(sessionId, context); - queue.put(sessionId, task); - task.future = timer.schedule(task, task.timeout, TimeUnit.MILLISECONDS); - return task; - } - - public PushTask getAndRemove(int sessionId) { - return queue.remove(sessionId); - } - - public final class PushTask extends FutureTask implements Runnable { - private PushCallback callback; - private final int timeout; - private final long sendTime; - private final int sessionId; - private Future future; - - private PushTask(int sessionId, PushContext context) { - super(NONE); - this.callback = context.getCallback(); - this.timeout = context.getTimeout(); - this.sendTime = System.currentTimeMillis(); - this.sessionId = sessionId; - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - throw new UnsupportedOperationException(); - } - - @Override - public void run() { - queue.remove(sessionId); - timeout(); - } - - public void timeout() { - call(false); - } - - public void success() { - call(true); - } - - private void call(boolean success) { - if (this.future.cancel(true)) { - this.set(success); - if (callback != null) { - if (success) callback.onSuccess(); - else callback.onTimeout(); - } - callback = null; - } - logger.d("one push task end, sessionId=%d, costTime=%d, success=%b", - sessionId, (System.currentTimeMillis() - sendTime), success); - } - } -} diff --git a/src/main/java/com/mpush/client/AckRequestMgr.java b/src/main/java/com/mpush/client/AckRequestMgr.java new file mode 100644 index 0000000..604b1de --- /dev/null +++ b/src/main/java/com/mpush/client/AckRequestMgr.java @@ -0,0 +1,171 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.client; + +import com.mpush.api.Logger; +import com.mpush.api.ack.AckCallback; +import com.mpush.api.ack.AckContext; +import com.mpush.api.ack.AckModel; +import com.mpush.api.connection.Connection; +import com.mpush.api.protocol.Packet; +import com.mpush.util.thread.ExecutorManager; + +import java.util.Map; +import java.util.concurrent.*; + +/** + * Created by ohun on 2016/11/13. + * + * @author ohun@live.cn (夜色) + */ +public final class AckRequestMgr { + private static AckRequestMgr I; + + private final Logger logger = ClientConfig.I.getLogger(); + + private final Map queue = new ConcurrentHashMap<>(); + private final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getHttpRequestThread(); + private final Callable NONE = new Callable() { + @Override + public Boolean call() throws Exception { + return Boolean.FALSE; + } + }; + private Connection connection; + + + public static AckRequestMgr I() { + if (I == null) { + synchronized (AckRequestMgr.class) { + if (I == null) { + I = new AckRequestMgr(); + } + } + } + return I; + } + + private AckRequestMgr() { + } + + public Future add(int sessionId, AckContext context) { + if (context.ackModel == AckModel.NO_ACK) return null; + if (context.callback == null) return null; + return addTask(new RequestTask(sessionId, context)); + } + + public RequestTask getAndRemove(int sessionId) { + return queue.remove(sessionId); + } + + + public void clear() { + for (RequestTask task : queue.values()) { + try { + task.future.cancel(true); + } catch (Exception e) { + } + } + } + + private RequestTask addTask(RequestTask task) { + queue.put(task.sessionId, task); + task.future = timer.schedule(task, task.timeout, TimeUnit.MILLISECONDS); + return task; + } + + public void setConnection(Connection connection) { + this.connection = connection; + } + + public final class RequestTask extends FutureTask implements Runnable { + private AckCallback callback; + private final int timeout; + private final long sendTime; + private final int sessionId; + private final Packet request; + private Future future; + private int retryCount; + + private RequestTask(AckCallback callback, int timeout, int sessionId, Packet request, int retryCount) { + super(NONE); + this.callback = callback; + this.timeout = timeout; + this.sendTime = System.currentTimeMillis(); + this.sessionId = sessionId; + this.request = request; + this.retryCount = retryCount; + } + + private RequestTask(int sessionId, AckContext context) { + this(context.callback, context.timeout, sessionId, context.request, context.retryCount); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + throw new UnsupportedOperationException(); + } + + @Override + public void run() { + queue.remove(sessionId); + timeout(); + } + + public void timeout() { + call(null); + } + + public void success(Packet packet) { + call(packet); + } + + private void call(Packet response) { + if (this.future.cancel(true)) { + boolean success = response != null; + this.set(success); + if (callback != null) { + if (success) { + logger.d("receive one ack response, sessionId=%d, costTime=%d, request=%s, response=%s" + , sessionId, (System.currentTimeMillis() - sendTime), request, response + ); + callback.onSuccess(response); + } else if (request != null && retryCount > 0) { + logger.w("one ack request timeout, retry=%d, sessionId=%d, costTime=%d, request=%s" + , retryCount, sessionId, (System.currentTimeMillis() - sendTime), request + ); + addTask(copy(retryCount - 1)); + connection.send(request); + } else { + logger.w("one ack request timeout, sessionId=%d, costTime=%d, request=%s" + , sessionId, (System.currentTimeMillis() - sendTime), request + ); + callback.onTimeout(request); + } + } + callback = null; + } + } + + private RequestTask copy(int retryCount) { + return new RequestTask(callback, timeout, sessionId, request, retryCount); + } + } +} diff --git a/src/main/java/com/mpush/handler/AckHandler.java b/src/main/java/com/mpush/handler/AckHandler.java index 8f107ca..bff2794 100644 --- a/src/main/java/com/mpush/handler/AckHandler.java +++ b/src/main/java/com/mpush/handler/AckHandler.java @@ -22,8 +22,8 @@ import com.mpush.api.Logger; import com.mpush.api.connection.Connection; import com.mpush.api.protocol.Packet; -import com.mpush.client.AckMessageQueue; import com.mpush.client.ClientConfig; +import com.mpush.client.AckRequestMgr; import com.mpush.message.AckMessage; /** @@ -33,13 +33,12 @@ */ public class AckHandler extends BaseMessageHandler { - private AckMessageQueue ackMessageQueue; + private final Logger logger; + private final AckRequestMgr ackRequestMgr; - private Logger logger; - - public AckHandler(AckMessageQueue ackMessageQueue) { - this.ackMessageQueue = ackMessageQueue; + public AckHandler() { this.logger = ClientConfig.I.getLogger(); + this.ackRequestMgr = AckRequestMgr.I(); } @Override @@ -49,11 +48,9 @@ public AckMessage decode(Packet packet, Connection connection) { @Override public void handle(AckMessage message) { - AckMessageQueue.PushTask task = ackMessageQueue.getAndRemove(message.getSessionId()); - if (task == null) { - logger.w("receive server ack, but timeout message={}", message); - return; + AckRequestMgr.RequestTask task = ackRequestMgr.getAndRemove(message.getSessionId()); + if (task != null) { + task.success(message.getPacket()); } - task.success(); } } From 085ee5796aace3faa2801f5c877f856945b9baa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 22:00:11 +0800 Subject: [PATCH 31/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AFACK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mpush/api/push/PushContext.java | 25 +++---------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/mpush/api/push/PushContext.java b/src/main/java/com/mpush/api/push/PushContext.java index 503d530..7939da7 100644 --- a/src/main/java/com/mpush/api/push/PushContext.java +++ b/src/main/java/com/mpush/api/push/PushContext.java @@ -20,17 +20,16 @@ package com.mpush.api.push; import com.mpush.api.Constants; +import com.mpush.api.ack.AckContext; +import com.mpush.api.ack.AckModel; /** * Created by ohun on 16/10/13. * * @author ohun@live.cn (夜色) */ -public final class PushContext { +public final class PushContext extends AckContext { public byte[] content; - public AckModel ackModel = AckModel.NO_ACK; - public PushCallback callback; - public int timeout = 1000; public PushContext(byte[] content) { this.content = content; @@ -61,22 +60,4 @@ public PushContext setAckModel(AckModel ackModel) { this.ackModel = ackModel; return this; } - - public PushCallback getCallback() { - return callback; - } - - public PushContext setCallback(PushCallback callback) { - this.callback = callback; - return this; - } - - public int getTimeout() { - return timeout; - } - - public PushContext setTimeout(int timeout) { - this.timeout = timeout; - return this; - } } From f3fb5fe70eb2dc5a7b1e5d359e4a2530e0e2fac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 22:03:04 +0800 Subject: [PATCH 32/53] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ttpRequestQueue.java => HttpRequestMgr.java} | 17 ++++++++++++++++- .../com/mpush/handler/HttpProxyHandler.java | 11 +++++------ 2 files changed, 21 insertions(+), 7 deletions(-) rename src/main/java/com/mpush/client/{HttpRequestQueue.java => HttpRequestMgr.java} (92%) diff --git a/src/main/java/com/mpush/client/HttpRequestQueue.java b/src/main/java/com/mpush/client/HttpRequestMgr.java similarity index 92% rename from src/main/java/com/mpush/client/HttpRequestQueue.java rename to src/main/java/com/mpush/client/HttpRequestMgr.java index 75c8097..51a1f18 100644 --- a/src/main/java/com/mpush/client/HttpRequestQueue.java +++ b/src/main/java/com/mpush/client/HttpRequestMgr.java @@ -43,7 +43,8 @@ * * @author ohun@live.cn */ -public final class HttpRequestQueue { +public final class HttpRequestMgr { + private static HttpRequestMgr I; private final Map queue = new ConcurrentHashMap<>(); private final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getHttpRequestThread(); private final Executor executor = ExecutorManager.INSTANCE.getDispatchThread(); @@ -57,6 +58,20 @@ public HttpResponse call() throws Exception { }; private final Logger logger = ClientConfig.I.getLogger(); + public static HttpRequestMgr I() { + if (I == null) { + synchronized (AckRequestMgr.class) { + if (I == null) { + I = new HttpRequestMgr(); + } + } + } + return I; + } + + private HttpRequestMgr() { + } + public Future add(int sessionId, HttpRequest request) { RequestTask task = new RequestTask(sessionId, request); queue.put(sessionId, task); diff --git a/src/main/java/com/mpush/handler/HttpProxyHandler.java b/src/main/java/com/mpush/handler/HttpProxyHandler.java index b2ae733..8ca9df5 100644 --- a/src/main/java/com/mpush/handler/HttpProxyHandler.java +++ b/src/main/java/com/mpush/handler/HttpProxyHandler.java @@ -20,11 +20,10 @@ package com.mpush.handler; - import com.mpush.api.connection.Connection; import com.mpush.api.http.HttpResponse; import com.mpush.api.protocol.Packet; -import com.mpush.client.HttpRequestQueue; +import com.mpush.client.HttpRequestMgr; import com.mpush.api.Logger; import com.mpush.client.ClientConfig; import com.mpush.message.HttpResponseMessage; @@ -36,10 +35,10 @@ */ public final class HttpProxyHandler extends BaseMessageHandler { private final Logger logger = ClientConfig.I.getLogger(); - private final HttpRequestQueue queue; + private final HttpRequestMgr httpRequestMgr; - public HttpProxyHandler(HttpRequestQueue queue) { - this.queue = queue; + public HttpProxyHandler() { + this.httpRequestMgr = HttpRequestMgr.I(); } @Override @@ -49,7 +48,7 @@ public HttpResponseMessage decode(Packet packet, Connection connection) { @Override public void handle(HttpResponseMessage message) { - HttpRequestQueue.RequestTask task = queue.getAndRemove(message.getSessionId()); + HttpRequestMgr.RequestTask task = httpRequestMgr.getAndRemove(message.getSessionId()); if (task != null) { HttpResponse response = new HttpResponse(message.statusCode, message.reasonPhrase, message.headers, message.body); task.setResponse(response); From 0dcde50a0f8869fb360efaa1c9cb6295352df19c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 22:03:41 +0800 Subject: [PATCH 33/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AFACK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/ClientConfig.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/com/mpush/client/ClientConfig.java b/src/main/java/com/mpush/client/ClientConfig.java index 58e3cd6..b32a5ef 100644 --- a/src/main/java/com/mpush/client/ClientConfig.java +++ b/src/main/java/com/mpush/client/ClientConfig.java @@ -55,7 +55,6 @@ public final class ClientConfig { private Logger logger; private boolean logEnabled; private boolean enableHttpProxy = true; - private boolean enableClientPush = true; public static ClientConfig build() { return I = new ClientConfig(); @@ -249,15 +248,6 @@ public ClientConfig setServerPort(int serverPort) { return this; } - public boolean isEnableClientPush() { - return enableClientPush; - } - - public ClientConfig setEnableClientPush(boolean enableClientPush) { - this.enableClientPush = enableClientPush; - return this; - } - public String getTags() { return tags; } From 0d6ff4cab17195df6e03dd41873b1dd0104a5f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sun, 13 Nov 2016 22:06:07 +0800 Subject: [PATCH 34/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AFACK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/api/Message.java | 4 + .../java/com/mpush/api/ack/AckContext.java | 2 +- .../mpush/client/DefaultClientListener.java | 1 + .../java/com/mpush/client/MPushClient.java | 74 ++++++++++++++----- .../com/mpush/client/MessageDispatcher.java | 10 +++ .../com/mpush/handler/BaseMessageHandler.java | 1 + .../java/com/mpush/message/BaseMessage.java | 26 +++++-- 7 files changed, 92 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/mpush/api/Message.java b/src/main/java/com/mpush/api/Message.java index 5b581cb..a4ee885 100644 --- a/src/main/java/com/mpush/api/Message.java +++ b/src/main/java/com/mpush/api/Message.java @@ -32,6 +32,10 @@ public interface Message { Connection getConnection(); + void decodeBody(); + + void encodeBody(); + void send(); void sendRaw(); diff --git a/src/main/java/com/mpush/api/ack/AckContext.java b/src/main/java/com/mpush/api/ack/AckContext.java index cc064e0..253f73e 100644 --- a/src/main/java/com/mpush/api/ack/AckContext.java +++ b/src/main/java/com/mpush/api/ack/AckContext.java @@ -31,7 +31,7 @@ public class AckContext { public AckModel ackModel = AckModel.AUTO_ACK; public int timeout = 1000; public Packet request; - public int retryCount = 1; + public int retryCount; public static AckContext build(AckCallback callback) { AckContext context = new AckContext(); diff --git a/src/main/java/com/mpush/client/DefaultClientListener.java b/src/main/java/com/mpush/client/DefaultClientListener.java index e51954d..ce4b274 100644 --- a/src/main/java/com/mpush/client/DefaultClientListener.java +++ b/src/main/java/com/mpush/client/DefaultClientListener.java @@ -57,6 +57,7 @@ public void run() { } }); } + AckRequestMgr.I().clear(); } @Override diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index ff11bf2..c72086f 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -22,6 +22,8 @@ import com.mpush.api.Client; import com.mpush.api.Logger; +import com.mpush.api.ack.AckCallback; +import com.mpush.api.ack.AckContext; import com.mpush.api.connection.SessionContext; import com.mpush.api.connection.SessionStorage; import com.mpush.api.http.HttpRequest; @@ -48,34 +50,34 @@ * * @author ohun@live.cn (夜色) */ -/*package*/final class MPushClient implements Client { +/*package*/final class MPushClient implements Client, AckCallback { + private enum State {Started, Shutdown, Destroyed} private final AtomicReference clientState = new AtomicReference<>(State.Shutdown); - private final MessageDispatcher receiver; private final TcpConnection connection; private final ClientConfig config; private final Logger logger; private int hbTimeoutTimes; - private HttpRequestQueue httpRequestQueue; - private AckMessageQueue ackMessageQueue; + private AckRequestMgr ackRequestMgr; + private HttpRequestMgr httpRequestMgr; /*package*/ MPushClient(ClientConfig config) { this.config = config; this.logger = config.getLogger(); - this.receiver = new MessageDispatcher(); - this.connection = new TcpConnection(this, receiver); + + MessageDispatcher receiver = new MessageDispatcher(); + if (config.isEnableHttpProxy()) { - this.httpRequestQueue = new HttpRequestQueue(); - this.receiver.register(Command.HTTP_PROXY, new HttpProxyHandler(httpRequestQueue)); + this.httpRequestMgr = HttpRequestMgr.I(); + receiver.register(Command.HTTP_PROXY, new HttpProxyHandler()); } - if (config.isEnableClientPush()) { - this.ackMessageQueue = new AckMessageQueue(); - this.receiver.register(Command.ACK, new AckHandler(ackMessageQueue)); - } + this.ackRequestMgr = AckRequestMgr.I(); + this.connection = new TcpConnection(this, receiver); + this.ackRequestMgr.setConnection(this.connection); } @Override @@ -164,9 +166,16 @@ public void fastConnect() { message.sessionId = session.sessionId; message.maxHeartbeat = config.getMaxHeartbeat(); message.minHeartbeat = config.getMinHeartbeat(); + message.encodeBody(); + ackRequestMgr.add(message.getSessionId(), AckContext + .build(this) + .setRequest(message.getPacket()) + .setTimeout(1000) + .setRetryCount(3) + ); + logger.w("<<< do fast connect, message=%s", message); message.sendRaw(); connection.getSessionContext().changeCipher(session.cipher); - logger.w("<<< do fast connect, message=%s", message); } @Override @@ -182,13 +191,20 @@ public void handshake() { message.clientVersion = config.getClientVersion(); message.maxHeartbeat = config.getMaxHeartbeat(); message.minHeartbeat = config.getMinHeartbeat(); + message.encodeBody(); + ackRequestMgr.add(message.getSessionId(), AckContext + .build(this) + .setTimeout(1000) + .setRequest(message.getPacket()) + .setRetryCount(3) + ); + logger.w("<<< do handshake, message=%s", message); message.send(); context.changeCipher(new AesCipher(message.clientKey, message.iv)); - logger.w("<<< do handshake, message=%s", message); } @Override - public void bindUser(String userId, String tags) { + public void bindUser(final String userId, final String tags) { if (Strings.isBlank(userId)) { logger.w("bind user is null"); return; @@ -203,12 +219,20 @@ public void bindUser(String userId, String tags) { } context.setBindUser(userId).setTags(tags); config.setUserId(userId).setTags(tags); - BindUserMessage + BindUserMessage message = BindUserMessage .buildBind(connection) .setUserId(userId) - .setTags(tags) - .send(); + .setTags(tags); + message.encodeBody(); + ackRequestMgr.add(message.getSessionId(), AckContext + .build(this) + .setTimeout(3000) + .setRequest(message.getPacket()) + .setRetryCount(5) + ); logger.w("<<< do bind user, userId=%s", userId); + message.send(); + } @Override @@ -243,7 +267,7 @@ public Future push(PushContext context) { message.addFlag(context.ackModel.flag); message.send(); logger.d("<<< send push message=%s", message); - return ackMessageQueue.add(message.getSessionId(), context); + return ackRequestMgr.add(message.getSessionId(), context); } return null; } @@ -258,8 +282,18 @@ public Future sendHttp(HttpRequest request) { message.body = request.getBody(); message.send(); logger.d("<<< send http proxy, request=%s", request); - return httpRequestQueue.add(message.getSessionId(), request); + return httpRequestMgr.add(message.getSessionId(), request); } return null; } + + @Override + public void onSuccess(Packet response) { + + } + + @Override + public void onTimeout(Packet request) { + this.connection.reconnect(); + } } diff --git a/src/main/java/com/mpush/client/MessageDispatcher.java b/src/main/java/com/mpush/client/MessageDispatcher.java index 89e4773..8995d24 100644 --- a/src/main/java/com/mpush/client/MessageDispatcher.java +++ b/src/main/java/com/mpush/client/MessageDispatcher.java @@ -42,6 +42,7 @@ public final class MessageDispatcher implements PacketReceiver { private final Executor executor = ExecutorManager.INSTANCE.getDispatchThread(); private final Map handlers = new HashMap<>(); private final Logger logger = ClientConfig.I.getLogger(); + private final AckRequestMgr ackRequestMgr; public MessageDispatcher() { register(Command.HEARTBEAT, new HeartbeatHandler()); @@ -51,6 +52,7 @@ public MessageDispatcher() { register(Command.OK, new OkMessageHandler()); register(Command.ERROR, new ErrorMessageHandler()); register(Command.PUSH, new PushMessageHandler()); + this.ackRequestMgr = AckRequestMgr.I(); } public void register(Command command, MessageHandler handler) { @@ -65,6 +67,7 @@ public void onReceive(final Packet packet, final Connection connection) { @Override public void run() { try { + doAckResponse(packet); handler.handle(packet, connection); } catch (Throwable throwable) { logger.e(throwable, "handle message error, packet=%s", packet); @@ -77,4 +80,11 @@ public void run() { connection.reconnect(); } } + + private void doAckResponse(Packet packet) { + AckRequestMgr.RequestTask task = ackRequestMgr.getAndRemove(packet.sessionId); + if (task != null) { + task.success(packet); + } + } } diff --git a/src/main/java/com/mpush/handler/BaseMessageHandler.java b/src/main/java/com/mpush/handler/BaseMessageHandler.java index 9230f73..acc6346 100644 --- a/src/main/java/com/mpush/handler/BaseMessageHandler.java +++ b/src/main/java/com/mpush/handler/BaseMessageHandler.java @@ -33,6 +33,7 @@ public abstract class BaseMessageHandler implements MessageHa public void handle(Packet packet, Connection connection) { T t = decode(packet, connection); if (t != null) { + t.decodeBody(); handle(t); } } diff --git a/src/main/java/com/mpush/message/BaseMessage.java b/src/main/java/com/mpush/message/BaseMessage.java index d072ca9..ae5786c 100644 --- a/src/main/java/com/mpush/message/BaseMessage.java +++ b/src/main/java/com/mpush/message/BaseMessage.java @@ -20,7 +20,6 @@ package com.mpush.message; - import com.mpush.util.IOUtils; import com.mpush.client.ClientConfig; import com.mpush.api.Message; @@ -36,17 +35,23 @@ * @author ohun@live.cn (夜色) */ public abstract class BaseMessage implements Message { + public static final int STATUS_DECODED = 1; + public static final int STATUS_ENCODED = 2; private static final AtomicInteger SID_SEQ = new AtomicInteger(); protected final Packet packet; protected final Connection connection; + protected int status = 0; public BaseMessage(Packet packet, Connection connection) { this.packet = packet; this.connection = connection; - this.decodeBody(); } - protected void decodeBody() { + @Override + public void decodeBody() { + if ((status & STATUS_DECODED) != 0) return; + else status |= STATUS_DECODED; + if (packet.body != null && packet.body.length > 0) { //1.解密 byte[] tmp = packet.body; @@ -70,7 +75,11 @@ protected void decodeBody() { } } - protected void encodeBody() { + @Override + public void encodeBody() { + if ((status & STATUS_ENCODED) != 0) return; + else status |= STATUS_ENCODED; + byte[] tmp = encode(); if (tmp != null && tmp.length > 0) { //1.压缩 @@ -95,6 +104,13 @@ protected void encodeBody() { } } + private void encodeBodyRaw() { + if ((status & STATUS_ENCODED) != 0) return; + else status |= STATUS_ENCODED; + + packet.body = encode(); + } + protected abstract void decode(byte[] body); protected abstract byte[] encode(); @@ -121,7 +137,7 @@ public void send() { @Override public void sendRaw() { - packet.body = encode(); + encodeBodyRaw(); connection.send(packet); } From 8f4a6d11ee341d9f95764f9e887eb766c77335af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Mon, 28 Nov 2016 14:06:55 +0800 Subject: [PATCH 35/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AFACK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/AckRequestMgr.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mpush/client/AckRequestMgr.java b/src/main/java/com/mpush/client/AckRequestMgr.java index 604b1de..7b17783 100644 --- a/src/main/java/com/mpush/client/AckRequestMgr.java +++ b/src/main/java/com/mpush/client/AckRequestMgr.java @@ -96,11 +96,11 @@ public void setConnection(Connection connection) { } public final class RequestTask extends FutureTask implements Runnable { - private AckCallback callback; private final int timeout; private final long sendTime; private final int sessionId; - private final Packet request; + private AckCallback callback; + private Packet request; private Future future; private int retryCount; @@ -161,6 +161,7 @@ private void call(Packet response) { } } callback = null; + request = null; } } From 461e0303677251a4c7a2125052121c2a97655765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Tue, 29 Nov 2016 20:05:04 +0800 Subject: [PATCH 36/53] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0v0.0.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5537064..5ef0e16 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.mpusher mpush-client-java - 0.0.5 + 0.0.6 jar mpush-client-java MPUSH消息推送客户端SDK From dea4f800cfc8dd4ae5381d6aef8be6b7d885f50e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Thu, 1 Dec 2016 22:13:15 +0800 Subject: [PATCH 37/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E5=8F=98=E5=8C=96=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/api/Client.java | 2 ++ src/main/java/com/mpush/client/MPushClient.java | 6 ++++++ src/test/java/com/mpush/client/MPushClientTest.java | 6 +++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/mpush/api/Client.java b/src/main/java/com/mpush/api/Client.java index 9a9f6b6..ef2f53a 100644 --- a/src/main/java/com/mpush/api/Client.java +++ b/src/main/java/com/mpush/api/Client.java @@ -37,4 +37,6 @@ public interface Client extends MPushProtocol { boolean isRunning(); + void onNetStateChange(boolean isConnected); + } diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index c72086f..51c4640 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -114,6 +114,12 @@ public boolean isRunning() { return clientState.get() == State.Started && connection.isConnected(); } + @Override + public void onNetStateChange(boolean isConnected) { + connection.setAutoConnect(isConnected); + if (isConnected) connection.connect(); + } + @Override public boolean healthCheck() { diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index a337dce..414c98e 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -36,7 +36,7 @@ */ public class MPushClientTest { private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB"; - private static final String allocServer = "http://127.0.0.1:9999/"; + private static final String allocServer = "http://103.246.161.44:9999/"; public static void main(String[] args) throws Exception { int count = 1; @@ -61,11 +61,11 @@ public static void main(String[] args) throws Exception { client = ClientConfig .build() .setPublicKey(publicKey) - //.setAllotServer(allocServer) + .setAllotServer(allocServer) .setServerHost(serverHost) .setServerPort(3000) .setDeviceId("deviceId-test" + i) - .setOsName("Android") + .setOsName("android") .setOsVersion("6.0") .setClientVersion("2.0") .setUserId("user-" + i) From f1ef543fa60341c08982ae6465b597be66a2765b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 2 Dec 2016 11:06:56 +0800 Subject: [PATCH 38/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E5=8F=98=E5=8C=96=E6=8E=A5=E5=8F=A3,=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BD=91=E7=BB=9C=E4=B8=8D=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mpush/api/connection/Connection.java | 5 ++- .../java/com/mpush/client/AckRequestMgr.java | 2 +- .../java/com/mpush/client/HttpRequestMgr.java | 3 +- .../java/com/mpush/client/MPushClient.java | 42 ++++++++++++++++++- .../java/com/mpush/client/TcpConnection.java | 10 +++++ .../mpush/util/thread/ExecutorManager.java | 20 ++++----- .../com/mpush/client/MPushClientTest.java | 2 +- 7 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/mpush/api/connection/Connection.java b/src/main/java/com/mpush/api/connection/Connection.java index 06a3b81..c962347 100644 --- a/src/main/java/com/mpush/api/connection/Connection.java +++ b/src/main/java/com/mpush/api/connection/Connection.java @@ -20,7 +20,6 @@ package com.mpush.api.connection; - import com.mpush.api.Client; import com.mpush.api.protocol.Packet; @@ -53,6 +52,10 @@ public interface Connection { void setLastWriteTime(); + void resetTimeout(); + + boolean isAutoConnect(); + SocketChannel getChannel(); Client getClient(); diff --git a/src/main/java/com/mpush/client/AckRequestMgr.java b/src/main/java/com/mpush/client/AckRequestMgr.java index 7b17783..7192bfe 100644 --- a/src/main/java/com/mpush/client/AckRequestMgr.java +++ b/src/main/java/com/mpush/client/AckRequestMgr.java @@ -41,7 +41,7 @@ public final class AckRequestMgr { private final Logger logger = ClientConfig.I.getLogger(); private final Map queue = new ConcurrentHashMap<>(); - private final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getHttpRequestThread(); + private final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getTimerThread(); private final Callable NONE = new Callable() { @Override public Boolean call() throws Exception { diff --git a/src/main/java/com/mpush/client/HttpRequestMgr.java b/src/main/java/com/mpush/client/HttpRequestMgr.java index 51a1f18..5f35271 100644 --- a/src/main/java/com/mpush/client/HttpRequestMgr.java +++ b/src/main/java/com/mpush/client/HttpRequestMgr.java @@ -36,7 +36,6 @@ import java.util.concurrent.TimeUnit; import static java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT; -import static java.net.HttpURLConnection.HTTP_NOT_FOUND; /** * Created by yxx on 2016/2/16. @@ -46,7 +45,7 @@ public final class HttpRequestMgr { private static HttpRequestMgr I; private final Map queue = new ConcurrentHashMap<>(); - private final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getHttpRequestThread(); + private final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getTimerThread(); private final Executor executor = ExecutorManager.INSTANCE.getDispatchThread(); //private final HttpResponse response404 = new HttpResponse(HTTP_NOT_FOUND, "Not Found", null, null); private final HttpResponse response408 = new HttpResponse(HTTP_CLIENT_TIMEOUT, "Request Timeout", null, null); diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index 51c4640..c8fe172 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -31,7 +31,6 @@ import com.mpush.api.protocol.Command; import com.mpush.api.protocol.Packet; import com.mpush.api.push.PushContext; -import com.mpush.handler.AckHandler; import com.mpush.handler.HttpProxyHandler; import com.mpush.message.*; import com.mpush.security.AesCipher; @@ -41,6 +40,8 @@ import com.mpush.util.thread.ExecutorManager; import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import static com.mpush.api.Constants.MAX_HB_TIMEOUT_COUNT; @@ -114,10 +115,47 @@ public boolean isRunning() { return clientState.get() == State.Started && connection.isConnected(); } + /** + * 这个方法主要用于解决网络十分不稳定的场景: + * 正常情况如果网络断开,就应该关闭连接,反之则应去建立连接 + * 但是在网络抖动厉害时就会发生连接频繁的建立/断开。 + *

+ * 处理这种场景的其中一个方案是: + * 当网络断开时不主动关闭连接,而是尝试发送一次心跳检测, + * 如果能收到响应,说明网络短时间内又恢复了, + * 否则就断开连接,等待网络恢复并重建连接。 + * + * @param isConnected true/false + */ @Override public void onNetStateChange(boolean isConnected) { connection.setAutoConnect(isConnected); - if (isConnected) connection.connect(); + + if (isConnected) { //当有网络时,去尝试重连 + connection.connect(); + } else if (connection.isConnected()) { //无网络,如果连接没有断开,尝试发送一次心跳检测,用于快速校验网络状况 + connection.resetTimeout();//心跳检测前,重置上次读写数据包的时间戳 + hbTimeoutTimes = MAX_HB_TIMEOUT_COUNT - 2;//总共要调用两次healthCheck,第一次用于发送心跳,第二次用于检测是否超时 + final ScheduledExecutorService timer = ExecutorManager.INSTANCE.getTimerThread(); + + //隔3s后发送一次心跳检测,看能不能收到服务端的响应 + timer.schedule(new Runnable() { + int checkCount = 0; + + @Override + public void run() { + //如果期间连接状态发生变化,取消任务 + if (connection.isAutoConnect() || !connection.isConnected()) return; + + if (++checkCount <= 2) { + if (healthCheck() && checkCount < 2) { + timer.schedule(this, 3, TimeUnit.SECONDS); + } + } + } + + }, 3, TimeUnit.SECONDS); + } } @Override diff --git a/src/main/java/com/mpush/client/TcpConnection.java b/src/main/java/com/mpush/client/TcpConnection.java index 724996e..e70af9f 100644 --- a/src/main/java/com/mpush/client/TcpConnection.java +++ b/src/main/java/com/mpush/client/TcpConnection.java @@ -261,6 +261,16 @@ public boolean isReadTimeout() { return System.currentTimeMillis() - lastReadTime > context.heartbeat + 1000; } + @Override + public void resetTimeout() { + lastReadTime = lastWriteTime = 0; + } + + @Override + public boolean isAutoConnect() { + return autoConnect; + } + @Override public SessionContext getSessionContext() { return context; diff --git a/src/main/java/com/mpush/util/thread/ExecutorManager.java b/src/main/java/com/mpush/util/thread/ExecutorManager.java index 124b498..7b38a71 100644 --- a/src/main/java/com/mpush/util/thread/ExecutorManager.java +++ b/src/main/java/com/mpush/util/thread/ExecutorManager.java @@ -40,12 +40,12 @@ public final class ExecutorManager { public static final String READ_THREAD_NAME = THREAD_NAME_PREFIX + "read-t"; public static final String DISPATCH_THREAD_NAME = THREAD_NAME_PREFIX + "dispatch-t"; public static final String START_THREAD_NAME = THREAD_NAME_PREFIX + "start-t"; - public static final String HTTP_THREAD_NAME = THREAD_NAME_PREFIX + "http-t"; + public static final String TIMER_THREAD_NAME = THREAD_NAME_PREFIX + "timer-t"; public static final ExecutorManager INSTANCE = new ExecutorManager(); private ThreadPoolExecutor writeThread; private ThreadPoolExecutor dispatchThread; private ThreadPoolExecutor startThread; - private ScheduledExecutorService httpRequestThread; + private ScheduledExecutorService timerThread; public ThreadPoolExecutor getWriteThread() { if (writeThread == null || writeThread.isShutdown()) { @@ -80,13 +80,13 @@ public ThreadPoolExecutor getStartThread() { return startThread; } - public ScheduledExecutorService getHttpRequestThread() { - if (httpRequestThread == null || httpRequestThread.isShutdown()) { - httpRequestThread = new ScheduledThreadPoolExecutor(1, - new NamedThreadFactory(HTTP_THREAD_NAME), + public ScheduledExecutorService getTimerThread() { + if (timerThread == null || timerThread.isShutdown()) { + timerThread = new ScheduledThreadPoolExecutor(1, + new NamedThreadFactory(TIMER_THREAD_NAME), new RejectedHandler()); } - return httpRequestThread; + return timerThread; } public synchronized void shutdown() { @@ -103,9 +103,9 @@ public synchronized void shutdown() { startThread = null; } - if (httpRequestThread != null) { - httpRequestThread.shutdownNow(); - httpRequestThread = null; + if (timerThread != null) { + timerThread.shutdownNow(); + timerThread = null; } } diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 414c98e..5f32514 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -106,7 +106,7 @@ public void onHandshakeOk(final Client client, final int heartbeat) { public void run() { client.healthCheck(); } - }, heartbeat, heartbeat, TimeUnit.MILLISECONDS); + }, 10, 10, TimeUnit.SECONDS); //client.push(PushContext.build("test")); From c8f289b722c5af200d24a5c9de1f285fa76f6691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 2 Dec 2016 11:14:23 +0800 Subject: [PATCH 39/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E5=8F=98=E5=8C=96=E6=8E=A5=E5=8F=A3,=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BD=91=E7=BB=9C=E4=B8=8D=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/MPushClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index c8fe172..d14d8de 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -130,7 +130,7 @@ public boolean isRunning() { @Override public void onNetStateChange(boolean isConnected) { connection.setAutoConnect(isConnected); - + logger.i("network state change, isConnected=%b, connection=%s", isConnected, connection); if (isConnected) { //当有网络时,去尝试重连 connection.connect(); } else if (connection.isConnected()) { //无网络,如果连接没有断开,尝试发送一次心跳检测,用于快速校验网络状况 @@ -144,6 +144,7 @@ public void onNetStateChange(boolean isConnected) { @Override public void run() { + logger.w("network disconnected, try test tcp connection checkCount=%d, connection=%s", checkCount, connection); //如果期间连接状态发生变化,取消任务 if (connection.isAutoConnect() || !connection.isConnected()) return; From d002e1d187cabb9e2e13c5693ea18185b0e33fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 2 Dec 2016 11:20:07 +0800 Subject: [PATCH 40/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E5=8F=98=E5=8C=96=E6=8E=A5=E5=8F=A3,=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BD=91=E7=BB=9C=E4=B8=8D=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/TcpConnection.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mpush/client/TcpConnection.java b/src/main/java/com/mpush/client/TcpConnection.java index e70af9f..63a5ad1 100644 --- a/src/main/java/com/mpush/client/TcpConnection.java +++ b/src/main/java/com/mpush/client/TcpConnection.java @@ -283,7 +283,14 @@ public boolean isWriteTimeout() { @Override public String toString() { - return "TcpConnection{" + ", lastReadTime=" + lastReadTime + ", lastWriteTime=" + lastWriteTime + ", context=" - + context + '}'; + return "TcpConnection{" + + "state=" + state + + ", channel=" + channel + + ", lastReadTime=" + lastReadTime + + ", lastWriteTime=" + lastWriteTime + + ", totalReconnectCount=" + totalReconnectCount + + ", reconnectCount=" + reconnectCount + + ", autoConnect=" + autoConnect + + '}'; } } From e0394647360be48b78de151427e9eda8e6eb1c93 Mon Sep 17 00:00:00 2001 From: maksim <154536744@qq.com> Date: Wed, 14 Dec 2016 13:39:19 +0800 Subject: [PATCH 41/53] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=9A=84keep-alive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/TcpConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/mpush/client/TcpConnection.java b/src/main/java/com/mpush/client/TcpConnection.java index 63a5ad1..2252616 100644 --- a/src/main/java/com/mpush/client/TcpConnection.java +++ b/src/main/java/com/mpush/client/TcpConnection.java @@ -38,6 +38,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; +import static com.mpush.api.Constants.DEFAULT_SO_TIMEOUT; import static com.mpush.api.Constants.MAX_RESTART_COUNT; import static com.mpush.api.Constants.MAX_TOTAL_RESTART_COUNT; import static com.mpush.client.TcpConnection.State.*; @@ -203,7 +204,6 @@ private boolean doConnect(String host, int port) { try { channel = SocketChannel.open(); channel.socket().setTcpNoDelay(true); - channel.socket().setKeepAlive(true); channel.connect(new InetSocketAddress(host, port)); logger.w("connect server ok [%s:%s]", host, port); onConnected(channel); From 9990aecd72cc37abdbdbea7f93fdb622c1a222a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Wed, 14 Dec 2016 13:40:21 +0800 Subject: [PATCH 42/53] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E8=B6=85=E6=97=B6?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E5=B8=B8=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/api/Constants.java | 2 ++ src/main/java/com/mpush/client/AllotClient.java | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mpush/api/Constants.java b/src/main/java/com/mpush/api/Constants.java index 402aa4e..a7f5332 100644 --- a/src/main/java/com/mpush/api/Constants.java +++ b/src/main/java/com/mpush/api/Constants.java @@ -30,6 +30,8 @@ public interface Constants { Charset UTF_8 = Charset.forName("UTF-8"); + int DEFAULT_SO_TIMEOUT = 1000 * 3;//客户端连接超时时间 + int DEFAULT_WRITE_TIMEOUT = 1000 * 10;//10s默认packet写超时 byte[] EMPTY_BYTES = new byte[0]; diff --git a/src/main/java/com/mpush/client/AllotClient.java b/src/main/java/com/mpush/client/AllotClient.java index 7aadc48..c65ddcc 100644 --- a/src/main/java/com/mpush/client/AllotClient.java +++ b/src/main/java/com/mpush/client/AllotClient.java @@ -35,6 +35,8 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import static com.mpush.api.Constants.DEFAULT_SO_TIMEOUT; + /** * Created by yxx on 2016/6/8. * @@ -65,8 +67,8 @@ public List queryServerAddressList() { try { URL url = new URL(config.getAllotServer()); connection = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(3000); - connection.setReadTimeout(3000); + connection.setConnectTimeout(DEFAULT_SO_TIMEOUT); + connection.setReadTimeout(DEFAULT_SO_TIMEOUT); connection.setUseCaches(false); connection.setDoInput(true); connection.setDoOutput(false); From f6392e92823bd795ee4c90ba31af9ae94b07231b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Wed, 28 Dec 2016 19:25:52 +0800 Subject: [PATCH 43/53] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mpush/message/BaseMessage.java | 6 +++--- .../mpush/util/thread/ExecutorManager.java | 19 +------------------ .../com/mpush/client/MPushClientTest.java | 1 - 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/mpush/message/BaseMessage.java b/src/main/java/com/mpush/message/BaseMessage.java index ae5786c..31545f1 100644 --- a/src/main/java/com/mpush/message/BaseMessage.java +++ b/src/main/java/com/mpush/message/BaseMessage.java @@ -35,12 +35,12 @@ * @author ohun@live.cn (夜色) */ public abstract class BaseMessage implements Message { - public static final int STATUS_DECODED = 1; - public static final int STATUS_ENCODED = 2; + public static final byte STATUS_DECODED = 1; + public static final byte STATUS_ENCODED = 2; private static final AtomicInteger SID_SEQ = new AtomicInteger(); protected final Packet packet; protected final Connection connection; - protected int status = 0; + protected byte status = 0; public BaseMessage(Packet packet, Connection connection) { this.packet = packet; diff --git a/src/main/java/com/mpush/util/thread/ExecutorManager.java b/src/main/java/com/mpush/util/thread/ExecutorManager.java index 7b38a71..f122863 100644 --- a/src/main/java/com/mpush/util/thread/ExecutorManager.java +++ b/src/main/java/com/mpush/util/thread/ExecutorManager.java @@ -44,7 +44,6 @@ public final class ExecutorManager { public static final ExecutorManager INSTANCE = new ExecutorManager(); private ThreadPoolExecutor writeThread; private ThreadPoolExecutor dispatchThread; - private ThreadPoolExecutor startThread; private ScheduledExecutorService timerThread; public ThreadPoolExecutor getWriteThread() { @@ -69,17 +68,6 @@ public ThreadPoolExecutor getDispatchThread() { return dispatchThread; } - public ThreadPoolExecutor getStartThread() { - if (startThread == null || startThread.isShutdown()) { - startThread = new ThreadPoolExecutor(1, 1, - 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue(1), - new NamedThreadFactory(START_THREAD_NAME), - new RejectedHandler()); - } - return startThread; - } - public ScheduledExecutorService getTimerThread() { if (timerThread == null || timerThread.isShutdown()) { timerThread = new ScheduledThreadPoolExecutor(1, @@ -98,11 +86,6 @@ public synchronized void shutdown() { dispatchThread.shutdownNow(); dispatchThread = null; } - if (startThread != null) { - startThread.shutdownNow(); - startThread = null; - - } if (timerThread != null) { timerThread.shutdownNow(); timerThread = null; @@ -117,7 +100,7 @@ private static class RejectedHandler implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { - ClientConfig.I.getLogger().w("a task was rejected execute=%s", executor); + ClientConfig.I.getLogger().w("a task was rejected r=%s", r); } } } diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 5f32514..d9dae12 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -22,7 +22,6 @@ import com.mpush.api.Client; import com.mpush.api.ClientListener; -import com.mpush.api.push.PushContext; import com.mpush.util.DefaultLogger; import java.util.concurrent.Executors; From cd688a173a82c9860c7c199db59a0c729e7923c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Fri, 20 Jan 2017 16:43:44 +0800 Subject: [PATCH 44/53] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20alloc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/com/mpush/client/MPushClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index d9dae12..536da60 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -35,7 +35,7 @@ */ public class MPushClientTest { private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB"; - private static final String allocServer = "http://103.246.161.44:9999/"; + private static final String allocServer = "http://103.60.220.145:9999/"; public static void main(String[] args) throws Exception { int count = 1; From 47df46732da2603bb5b92266686b6159ed64a4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Thu, 23 Feb 2017 16:11:16 +0800 Subject: [PATCH 45/53] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20alloc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/mpush/client/MessageDispatcher.java | 5 +++-- src/main/java/com/mpush/handler/AckHandler.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/mpush/client/MessageDispatcher.java b/src/main/java/com/mpush/client/MessageDispatcher.java index 8995d24..8e26786 100644 --- a/src/main/java/com/mpush/client/MessageDispatcher.java +++ b/src/main/java/com/mpush/client/MessageDispatcher.java @@ -52,6 +52,7 @@ public MessageDispatcher() { register(Command.OK, new OkMessageHandler()); register(Command.ERROR, new ErrorMessageHandler()); register(Command.PUSH, new PushMessageHandler()); + register(Command.ACK, new AckHandler()); this.ackRequestMgr = AckRequestMgr.I(); } @@ -76,8 +77,8 @@ public void run() { } }); } else { - logger.w("<<< receive unsupported message, do reconnect, packet=%s", packet); - connection.reconnect(); + logger.w("<<< receive unsupported message, packet=%s", packet); + //connection.reconnect(); } } diff --git a/src/main/java/com/mpush/handler/AckHandler.java b/src/main/java/com/mpush/handler/AckHandler.java index bff2794..9e946e9 100644 --- a/src/main/java/com/mpush/handler/AckHandler.java +++ b/src/main/java/com/mpush/handler/AckHandler.java @@ -48,9 +48,9 @@ public AckMessage decode(Packet packet, Connection connection) { @Override public void handle(AckMessage message) { - AckRequestMgr.RequestTask task = ackRequestMgr.getAndRemove(message.getSessionId()); + /*AckRequestMgr.RequestTask task = ackRequestMgr.getAndRemove(message.getSessionId()); if (task != null) { task.success(message.getPacket()); - } + }*/ } } From 72904f75fb30b58d3e3b768059ce3c7f2826f5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Thu, 23 Feb 2017 16:12:13 +0800 Subject: [PATCH 46/53] register ack handler --- src/main/java/com/mpush/client/MessageDispatcher.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/mpush/client/MessageDispatcher.java b/src/main/java/com/mpush/client/MessageDispatcher.java index 8e26786..59bea40 100644 --- a/src/main/java/com/mpush/client/MessageDispatcher.java +++ b/src/main/java/com/mpush/client/MessageDispatcher.java @@ -53,6 +53,7 @@ public MessageDispatcher() { register(Command.ERROR, new ErrorMessageHandler()); register(Command.PUSH, new PushMessageHandler()); register(Command.ACK, new AckHandler()); + this.ackRequestMgr = AckRequestMgr.I(); } From 7ec1d8d0a2841f366d38d6ec4c22234c29f02a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Thu, 9 Mar 2017 09:56:28 +0800 Subject: [PATCH 47/53] add alloc log --- src/main/java/com/mpush/client/AllotClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/mpush/client/AllotClient.java b/src/main/java/com/mpush/client/AllotClient.java index c65ddcc..1c4cbef 100644 --- a/src/main/java/com/mpush/client/AllotClient.java +++ b/src/main/java/com/mpush/client/AllotClient.java @@ -79,7 +79,7 @@ public List queryServerAddressList() { return serverAddress; } } catch (IOException e) { - logger.e(e, "get server address ex, when connect server."); + logger.e(e, "get server address ex, when connect server. allot=%s", config.getAllotServer()); return Collections.emptyList(); } From f5833a44f0313fa912d2212d75bf6dbe925f7642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Thu, 17 Aug 2017 15:43:33 +0800 Subject: [PATCH 48/53] =?UTF-8?q?AllotClient=E5=A2=9E=E5=8A=A0https?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mpush/client/AllotClient.java | 52 +++++++++++++++++-- src/main/java/com/mpush/util/MPUtils.java | 21 ++++++++ 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/mpush/client/AllotClient.java b/src/main/java/com/mpush/client/AllotClient.java index 1c4cbef..3d14d09 100644 --- a/src/main/java/com/mpush/client/AllotClient.java +++ b/src/main/java/com/mpush/client/AllotClient.java @@ -24,16 +24,19 @@ import com.mpush.api.Logger; import com.mpush.util.IOUtils; +import javax.net.ssl.*; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; import static com.mpush.api.Constants.DEFAULT_SO_TIMEOUT; @@ -67,6 +70,10 @@ public List queryServerAddressList() { try { URL url = new URL(config.getAllotServer()); connection = (HttpURLConnection) url.openConnection(); + if (config.getAllotServer().startsWith("https")) { + ((HttpsURLConnection) connection).setSSLSocketFactory(getSSLSocketFactory()); + ((HttpsURLConnection) connection).setHostnameVerifier(new NullHostnameVerifier()); + } connection.setConnectTimeout(DEFAULT_SO_TIMEOUT); connection.setReadTimeout(DEFAULT_SO_TIMEOUT); connection.setUseCaches(false); @@ -78,7 +85,7 @@ public List queryServerAddressList() { connection.disconnect(); return serverAddress; } - } catch (IOException e) { + } catch (Exception e) { logger.e(e, "get server address ex, when connect server. allot=%s", config.getAllotServer()); return Collections.emptyList(); } @@ -105,9 +112,7 @@ public List queryServerAddressList() { String result = new String(content, Constants.UTF_8); logger.w("get server address success result=%s", result); List serverAddress = new ArrayList<>(); - for (String s : result.split(",")) { - serverAddress.add(s); - } + serverAddress.addAll(Arrays.asList(result.split(","))); this.serverAddress = serverAddress; } else { logger.w("get server address failure return content empty."); @@ -115,4 +120,41 @@ public List queryServerAddressList() { return serverAddress; } + + private SSLSocketFactory getSSLSocketFactory() { + return getTrustAllContext().getSocketFactory(); + } + + private SSLContext getTrustAllContext() { + SSLContext sslContext = null; + try { + sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new SecureRandom()); + } catch (Exception e) { + throw new RuntimeException(e); + } + return sslContext; + } + + private static class TrustAnyTrustManager implements X509TrustManager { + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + } + + private static class NullHostnameVerifier implements HostnameVerifier { + + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + } } diff --git a/src/main/java/com/mpush/util/MPUtils.java b/src/main/java/com/mpush/util/MPUtils.java index 683ec79..4265ee7 100644 --- a/src/main/java/com/mpush/util/MPUtils.java +++ b/src/main/java/com/mpush/util/MPUtils.java @@ -24,6 +24,7 @@ import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; +import java.util.regex.Pattern; /** * Created by ohun on 2016/1/25. @@ -32,6 +33,19 @@ */ public final class MPUtils { + /** + * Quick and dirty pattern to differentiate IP addresses from hostnames. This is an approximation + * of Android's private InetAddress#isNumeric API. + *

+ *

This matches IPv6 addresses as a hex string containing at least one colon, and possibly + * including dots after the first colon. It matches IPv4 addresses as strings containing only + * decimal digits and dots. This pattern matches strings like "a:.23" and "54" that are neither IP + * addresses nor hostnames; they will be verified as IP addresses (which is a more strict + * verification). + */ + private static final Pattern VERIFY_AS_IP_ADDRESS = Pattern.compile( + "([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)"); + public static String parseHost2Ip(String host) { InetAddress ia = null; try { @@ -79,4 +93,11 @@ public static Map headerFromString(String headersString) { } return headers; } + + /** + * Returns true if {@code host} is not a host name and might be an IP address. + */ + public static boolean verifyAsIpAddress(String host) { + return VERIFY_AS_IP_ADDRESS.matcher(host).matches(); + } } From 2f5543a70fcbe09f745d6ee074d0cc0e0591ef15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Thu, 17 Aug 2017 15:44:05 +0800 Subject: [PATCH 49/53] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=88=B00.8.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5ef0e16..546f377 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.mpusher mpush-client-java - 0.0.6 + 0.8.0 jar mpush-client-java MPUSH消息推送客户端SDK From 70d11a12389e0ba0d8671c97db5f7b9e17683cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sat, 9 Jun 2018 17:33:51 +0800 Subject: [PATCH 50/53] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0ErrorCode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mpush/api/protocol/ErrorCode.java | 55 +++++++++++++++++++ .../mpush/handler/ErrorMessageHandler.java | 14 +++-- 2 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/mpush/api/protocol/ErrorCode.java diff --git a/src/main/java/com/mpush/api/protocol/ErrorCode.java b/src/main/java/com/mpush/api/protocol/ErrorCode.java new file mode 100644 index 0000000..9420436 --- /dev/null +++ b/src/main/java/com/mpush/api/protocol/ErrorCode.java @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api.protocol; + +/** + * Created by ohun on 2015/12/30. + * + * @author ohun@live.cn + */ +public enum ErrorCode { + OFFLINE(1, "user offline"), + PUSH_CLIENT_FAILURE(2, "push to client failure"), + ROUTER_CHANGE(3, "router change"), + ACK_TIMEOUT(4, "ack timeout"), + DISPATCH_ERROR(100, "handle message error"), + UNSUPPORTED_CMD(101, "unsupported command"), + REPEAT_HANDSHAKE(102, "repeat handshake"), + SESSION_EXPIRED(103, "session expired"), + INVALID_DEVICE(104, "invalid device"), + UNKNOWN(-1, "unknown"); + + ErrorCode(int code, String errorMsg) { + this.errorMsg = errorMsg; + this.errorCode = (byte) code; + } + + public final byte errorCode; + public final String errorMsg; + + public static ErrorCode toEnum(int code) { + for (ErrorCode errorCode : values()) { + if (errorCode.errorCode == code) { + return errorCode; + } + } + return UNKNOWN; + } +} diff --git a/src/main/java/com/mpush/handler/ErrorMessageHandler.java b/src/main/java/com/mpush/handler/ErrorMessageHandler.java index c5aa8cb..1de83be 100644 --- a/src/main/java/com/mpush/handler/ErrorMessageHandler.java +++ b/src/main/java/com/mpush/handler/ErrorMessageHandler.java @@ -20,13 +20,14 @@ package com.mpush.handler; - +import com.mpush.api.Logger; import com.mpush.api.connection.Connection; import com.mpush.api.protocol.Command; -import com.mpush.message.ErrorMessage; -import com.mpush.client.ClientConfig; -import com.mpush.api.Logger; import com.mpush.api.protocol.Packet; +import com.mpush.client.ClientConfig; +import com.mpush.message.ErrorMessage; + +import static com.mpush.api.protocol.ErrorCode.REPEAT_HANDSHAKE; /** * Created by ohun on 2015/12/30. @@ -48,7 +49,10 @@ public void handle(ErrorMessage message) { ClientConfig.I.getSessionStorage().clearSession(); message.getConnection().getClient().handshake(); } else if (message.cmd == Command.HANDSHAKE.cmd) { - message.getConnection().getClient().stop(); + if (message.code != REPEAT_HANDSHAKE.errorCode //重复握手的错误消息直接忽略 + && !REPEAT_HANDSHAKE.errorMsg.equals(message.reason)) { + message.getConnection().getClient().stop(); + } } else { message.getConnection().reconnect(); } From 0f4357bc11a77fa82755357dea9fcbd5e2c9c919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sat, 9 Jun 2018 17:36:13 +0800 Subject: [PATCH 51/53] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8F=A1=E6=89=8B?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E5=AF=BC=E8=87=B4=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?AES=E8=A7=A3=E5=AF=86=E9=94=99=E8=AF=AFbug,=20=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E5=A2=9E=E5=8A=A0=E6=8F=A1=E6=89=8B=E5=92=8C=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E8=B6=85=E6=97=B6=E6=97=B6=E9=97=B4=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mpush/client/ClientConfig.java | 36 +++++++++++++++++++ .../java/com/mpush/client/MPushClient.java | 36 ++++++++++++------- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/mpush/client/ClientConfig.java b/src/main/java/com/mpush/client/ClientConfig.java index b32a5ef..27c3803 100644 --- a/src/main/java/com/mpush/client/ClientConfig.java +++ b/src/main/java/com/mpush/client/ClientConfig.java @@ -55,6 +55,10 @@ public final class ClientConfig { private Logger logger; private boolean logEnabled; private boolean enableHttpProxy = true; + private int handshakeTimeoutMills = 3000; + private int handshakeRetryCount = 0; + private int bindUserTimeoutMills = 3000; + private int bindUserRetryCount = 1; public static ClientConfig build() { return I = new ClientConfig(); @@ -256,4 +260,36 @@ public ClientConfig setTags(String tags) { this.tags = tags; return this; } + + public int getHandshakeTimeoutMills() { + return handshakeTimeoutMills; + } + + public void setHandshakeTimeoutMills(int handshakeTimeoutMills) { + this.handshakeTimeoutMills = handshakeTimeoutMills; + } + + public int getHandshakeRetryCount() { + return handshakeRetryCount; + } + + public void setHandshakeRetryCount(int handshakeRetryCount) { + this.handshakeRetryCount = handshakeRetryCount; + } + + public int getBindUserTimeoutMills() { + return bindUserTimeoutMills; + } + + public void setBindUserTimeoutMills(int bindUserTimeoutMills) { + this.bindUserTimeoutMills = bindUserTimeoutMills; + } + + public int getBindUserRetryCount() { + return bindUserRetryCount; + } + + public void setBindUserRetryCount(int bindUserRetryCount) { + this.bindUserRetryCount = bindUserRetryCount; + } } diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index d14d8de..ca1c381 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -215,8 +215,8 @@ public void fastConnect() { ackRequestMgr.add(message.getSessionId(), AckContext .build(this) .setRequest(message.getPacket()) - .setTimeout(1000) - .setRetryCount(3) + .setTimeout(config.getHandshakeTimeoutMills()) + .setRetryCount(config.getHandshakeRetryCount()) ); logger.w("<<< do fast connect, message=%s", message); message.sendRaw(); @@ -239,9 +239,9 @@ public void handshake() { message.encodeBody(); ackRequestMgr.add(message.getSessionId(), AckContext .build(this) - .setTimeout(1000) .setRequest(message.getPacket()) - .setRetryCount(3) + .setTimeout(config.getHandshakeTimeoutMills()) + .setRetryCount(config.getHandshakeRetryCount()) ); logger.w("<<< do handshake, message=%s", message); message.send(); @@ -250,6 +250,11 @@ public void handshake() { @Override public void bindUser(final String userId, final String tags) { + if (!connection.getSessionContext().handshakeOk()) { + logger.w("connection is not handshake ok!"); + return; + } + if (Strings.isBlank(userId)) { logger.w("bind user is null"); return; @@ -271,9 +276,9 @@ public void bindUser(final String userId, final String tags) { message.encodeBody(); ackRequestMgr.add(message.getSessionId(), AckContext .build(this) - .setTimeout(3000) .setRequest(message.getPacket()) - .setRetryCount(5) + .setTimeout(config.getBindUserTimeoutMills()) + .setRetryCount(config.getBindUserRetryCount()) ); logger.w("<<< do bind user, userId=%s", userId); message.send(); @@ -282,6 +287,10 @@ public void bindUser(final String userId, final String tags) { @Override public void unbindUser() { + if (!connection.getSessionContext().handshakeOk()) { + logger.w("connection is not handshake ok!"); + return; + } String userId = config.getUserId(); if (Strings.isBlank(userId)) { logger.w("unbind user is null"); @@ -307,14 +316,15 @@ public void ack(int messageId) { @Override public Future push(PushContext context) { - if (connection.getSessionContext().handshakeOk()) { - PushMessage message = new PushMessage(context.content, connection); - message.addFlag(context.ackModel.flag); - message.send(); - logger.d("<<< send push message=%s", message); - return ackRequestMgr.add(message.getSessionId(), context); + if (!connection.getSessionContext().handshakeOk()) { + logger.w("connection is not handshake ok!"); + return null; } - return null; + PushMessage message = new PushMessage(context.content, connection); + message.addFlag(context.ackModel.flag); + message.send(); + logger.d("<<< send push message=%s", message); + return ackRequestMgr.add(message.getSessionId(), context); } @Override From 9967769b0819207605a3580ee1d662c12bb157eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sat, 9 Jun 2018 17:36:43 +0800 Subject: [PATCH 52/53] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=88=B00.8.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 546f377..ce0c433 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.mpusher mpush-client-java - 0.8.0 + 0.8.1 jar mpush-client-java MPUSH消息推送客户端SDK From e5fb89fefa020ef9be5b2b325d8b7af13e0eed77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E8=89=B2?= Date: Sat, 29 Sep 2018 16:31:06 +0800 Subject: [PATCH 53/53] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E5=AF=BC=E8=87=B4=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?AES=E8=A7=A3=E5=AF=86=E9=94=99=E8=AF=AFbug,=20=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E5=A2=9E=E5=8A=A0=E8=B6=85=E6=97=B6=E9=87=8D=E8=AF=95?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mpush/api/ack/AckContext.java | 10 ++++++ .../com/mpush/api/ack/RetryCondition.java | 32 +++++++++++++++++++ .../com/mpush/api/connection/Connection.java | 11 +++---- .../java/com/mpush/client/AckRequestMgr.java | 30 ++++++++++------- .../java/com/mpush/client/MPushClient.java | 8 +++++ .../com/mpush/client/MPushClientTest.java | 2 +- 6 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/mpush/api/ack/RetryCondition.java diff --git a/src/main/java/com/mpush/api/ack/AckContext.java b/src/main/java/com/mpush/api/ack/AckContext.java index 253f73e..21f5b32 100644 --- a/src/main/java/com/mpush/api/ack/AckContext.java +++ b/src/main/java/com/mpush/api/ack/AckContext.java @@ -32,6 +32,7 @@ public class AckContext { public int timeout = 1000; public Packet request; public int retryCount; + public RetryCondition retryCondition; public static AckContext build(AckCallback callback) { AckContext context = new AckContext(); @@ -83,4 +84,13 @@ public AckContext setRetryCount(int retryCount) { this.retryCount = retryCount; return this; } + + public RetryCondition getRetryCondition() { + return retryCondition; + } + + public AckContext setRetryCondition(RetryCondition retryCondition) { + this.retryCondition = retryCondition; + return this; + } } diff --git a/src/main/java/com/mpush/api/ack/RetryCondition.java b/src/main/java/com/mpush/api/ack/RetryCondition.java new file mode 100644 index 0000000..80f09db --- /dev/null +++ b/src/main/java/com/mpush/api/ack/RetryCondition.java @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2015-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * ohun@live.cn (夜色) + */ + +package com.mpush.api.ack; + +import com.mpush.api.connection.Connection; +import com.mpush.api.protocol.Packet; + +/** + * Created by ohun on 18/9/29. + * + * @author ohun@live.cn (夜色) + */ +public interface RetryCondition { + boolean test(Connection connection, Packet packet); +} diff --git a/src/main/java/com/mpush/api/connection/Connection.java b/src/main/java/com/mpush/api/connection/Connection.java index c962347..1d75ace 100644 --- a/src/main/java/com/mpush/api/connection/Connection.java +++ b/src/main/java/com/mpush/api/connection/Connection.java @@ -34,15 +34,15 @@ public interface Connection { void connect(); - SessionContext getSessionContext(); + void close(); - void send(Packet packet); + void reconnect(); - void close(); + void send(Packet packet);//TODO add send Listener boolean isConnected(); - void reconnect(); + boolean isAutoConnect(); boolean isReadTimeout(); @@ -54,10 +54,9 @@ public interface Connection { void resetTimeout(); - boolean isAutoConnect(); + SessionContext getSessionContext(); SocketChannel getChannel(); Client getClient(); - } diff --git a/src/main/java/com/mpush/client/AckRequestMgr.java b/src/main/java/com/mpush/client/AckRequestMgr.java index 7192bfe..76e6f32 100644 --- a/src/main/java/com/mpush/client/AckRequestMgr.java +++ b/src/main/java/com/mpush/client/AckRequestMgr.java @@ -23,6 +23,7 @@ import com.mpush.api.ack.AckCallback; import com.mpush.api.ack.AckContext; import com.mpush.api.ack.AckModel; +import com.mpush.api.ack.RetryCondition; import com.mpush.api.connection.Connection; import com.mpush.api.protocol.Packet; import com.mpush.util.thread.ExecutorManager; @@ -103,8 +104,9 @@ public final class RequestTask extends FutureTask implements Runnable { private Packet request; private Future future; private int retryCount; + private RetryCondition retryCondition; - private RequestTask(AckCallback callback, int timeout, int sessionId, Packet request, int retryCount) { + private RequestTask(AckCallback callback, int timeout, int sessionId, Packet request, int retryCount, RetryCondition retryCondition) { super(NONE); this.callback = callback; this.timeout = timeout; @@ -112,10 +114,11 @@ private RequestTask(AckCallback callback, int timeout, int sessionId, Packet req this.sessionId = sessionId; this.request = request; this.retryCount = retryCount; + this.retryCondition = retryCondition; } private RequestTask(int sessionId, AckContext context) { - this(context.callback, context.timeout, sessionId, context.request, context.retryCount); + this(context.callback, context.timeout, sessionId, context.request, context.retryCount, context.retryCondition); } @Override @@ -144,29 +147,32 @@ private void call(Packet response) { if (callback != null) { if (success) { logger.d("receive one ack response, sessionId=%d, costTime=%d, request=%s, response=%s" - , sessionId, (System.currentTimeMillis() - sendTime), request, response - ); + , sessionId, (System.currentTimeMillis() - sendTime), request, response); callback.onSuccess(response); } else if (request != null && retryCount > 0) { - logger.w("one ack request timeout, retry=%d, sessionId=%d, costTime=%d, request=%s" - , retryCount, sessionId, (System.currentTimeMillis() - sendTime), request - ); - addTask(copy(retryCount - 1)); - connection.send(request); + if (retryCondition == null || retryCondition.test(connection, request)) { + logger.w("one ack request timeout, retry=%d, sessionId=%d, costTime=%d, request=%s" + , retryCount, sessionId, (System.currentTimeMillis() - sendTime), request); + addTask(copy(retryCount - 1)); + connection.send(request); + } else { + logger.w("one ack request timeout, but ignore by condition, retry=%d, sessionId=%d, costTime=%d, request=%s" + , retryCount, sessionId, (System.currentTimeMillis() - sendTime), request); + } } else { logger.w("one ack request timeout, sessionId=%d, costTime=%d, request=%s" - , sessionId, (System.currentTimeMillis() - sendTime), request - ); + , sessionId, (System.currentTimeMillis() - sendTime), request); callback.onTimeout(request); } } callback = null; request = null; + retryCondition = null; } } private RequestTask copy(int retryCount) { - return new RequestTask(callback, timeout, sessionId, request, retryCount); + return new RequestTask(callback, timeout, sessionId, request, retryCount, retryCondition); } } } diff --git a/src/main/java/com/mpush/client/MPushClient.java b/src/main/java/com/mpush/client/MPushClient.java index ca1c381..fe5bc82 100644 --- a/src/main/java/com/mpush/client/MPushClient.java +++ b/src/main/java/com/mpush/client/MPushClient.java @@ -24,6 +24,8 @@ import com.mpush.api.Logger; import com.mpush.api.ack.AckCallback; import com.mpush.api.ack.AckContext; +import com.mpush.api.ack.RetryCondition; +import com.mpush.api.connection.Connection; import com.mpush.api.connection.SessionContext; import com.mpush.api.connection.SessionStorage; import com.mpush.api.http.HttpRequest; @@ -279,6 +281,12 @@ public void bindUser(final String userId, final String tags) { .setRequest(message.getPacket()) .setTimeout(config.getBindUserTimeoutMills()) .setRetryCount(config.getBindUserRetryCount()) + .setRetryCondition(new RetryCondition() { + @Override + public boolean test(Connection connection, Packet packet) { + return connection.getSessionContext().handshakeOk(); + } + }) ); logger.w("<<< do bind user, userId=%s", userId); message.send(); diff --git a/src/test/java/com/mpush/client/MPushClientTest.java b/src/test/java/com/mpush/client/MPushClientTest.java index 536da60..5068191 100644 --- a/src/test/java/com/mpush/client/MPushClientTest.java +++ b/src/test/java/com/mpush/client/MPushClientTest.java @@ -60,7 +60,7 @@ public static void main(String[] args) throws Exception { client = ClientConfig .build() .setPublicKey(publicKey) - .setAllotServer(allocServer) + //.setAllotServer(allocServer) .setServerHost(serverHost) .setServerPort(3000) .setDeviceId("deviceId-test" + i)