headers;
41 | public byte[] body;
42 |
43 | public HttpResponseMessage(Packet message, Connection connection) {
44 | super(message, connection);
45 | }
46 |
47 | @Override
48 | public void decode(ByteBuffer body) {
49 | statusCode = decodeInt(body);
50 | reasonPhrase = decodeString(body);
51 | headers = MPUtils.headerFromString(decodeString(body));
52 | this.body = decodeBytes(body);
53 | }
54 |
55 | @Override
56 | public void encode(ByteBuf body) {
57 | encodeInt(body, statusCode);
58 | encodeString(body, reasonPhrase);
59 | encodeString(body, MPUtils.headerToString(headers));
60 | encodeBytes(body, this.body);
61 | }
62 |
63 | public static HttpResponseMessage from(HttpRequestMessage src) {
64 | return new HttpResponseMessage(src.createResponse(), src.connection);
65 | }
66 |
67 | public HttpResponseMessage setStatusCode(int statusCode) {
68 | this.statusCode = statusCode;
69 | return this;
70 | }
71 |
72 | public HttpResponseMessage setReasonPhrase(String reasonPhrase) {
73 | this.reasonPhrase = reasonPhrase;
74 | return this;
75 | }
76 |
77 | public HttpResponseMessage addHeader(String name, String value) {
78 | if (headers == null) headers = new HashMap<>();
79 | this.headers.put(name, value);
80 | return this;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/message/KickUserMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.message;
21 |
22 |
23 |
24 | import com.mpush.api.connection.Connection;
25 | import com.mpush.api.protocol.Command;
26 | import com.mpush.api.protocol.Packet;
27 | import com.mpush.util.ByteBuf;
28 |
29 | import java.nio.ByteBuffer;
30 |
31 | /**
32 | * Created by ohun on 2015/12/29.
33 | *
34 | * @author ohun@live.cn (夜色)
35 | */
36 | public final class KickUserMessage extends ByteBufMessage {
37 | public String deviceId;
38 | public String userId;
39 |
40 | public KickUserMessage(Connection connection) {
41 | super(new Packet(Command.KICK), connection);
42 | }
43 |
44 | public KickUserMessage(Packet message, Connection connection) {
45 | super(message, connection);
46 | }
47 |
48 | @Override
49 | public void decode(ByteBuffer body) {
50 | deviceId = decodeString(body);
51 | userId = decodeString(body);
52 | }
53 |
54 | @Override
55 | public void encode(ByteBuf body) {
56 | encodeString(body, deviceId);
57 | encodeString(body, userId);
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return "KickUserMessage{" +
63 | "deviceId='" + deviceId + '\'' +
64 | ", userId='" + userId + '\'' +
65 | '}';
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/message/OkMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.message;
21 |
22 |
23 |
24 | import com.mpush.api.protocol.Command;
25 | import com.mpush.api.connection.Connection;
26 | import com.mpush.api.protocol.Packet;
27 | import com.mpush.util.ByteBuf;
28 |
29 | import java.nio.ByteBuffer;
30 |
31 | /**
32 | * Created by ohun on 2015/12/28.
33 | *
34 | * @author ohun@live.cn (夜色)
35 | */
36 | public final class OkMessage extends ByteBufMessage {
37 | public byte cmd;
38 | public byte code;
39 | public String data;
40 |
41 | public OkMessage(byte cmd, Packet message, Connection connection) {
42 | super(message, connection);
43 | this.cmd = cmd;
44 | }
45 |
46 | public OkMessage(Packet message, Connection connection) {
47 | super(message, connection);
48 | }
49 |
50 | @Override
51 | public void decode(ByteBuffer body) {
52 | cmd = decodeByte(body);
53 | code = decodeByte(body);
54 | data = decodeString(body);
55 | }
56 |
57 | @Override
58 | public void encode(ByteBuf body) {
59 | encodeByte(body, cmd);
60 | encodeByte(body, code);
61 | encodeString(body, data);
62 | }
63 |
64 | public static OkMessage from(BaseMessage src) {
65 | return new OkMessage(src.packet.cmd, new Packet(Command.OK
66 | , src.packet.sessionId), src.connection);
67 | }
68 |
69 | public OkMessage setCode(byte code) {
70 | this.code = code;
71 | return this;
72 | }
73 |
74 | public OkMessage setData(String data) {
75 | this.data = data;
76 | return this;
77 | }
78 |
79 | @Override
80 | public String toString() {
81 | return "OkMessage{" +
82 | "cmd=" + cmd +
83 | ", code=" + code +
84 | ", data='" + data + '\'' +
85 | '}';
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/message/PushMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.message;
21 |
22 |
23 | import com.mpush.api.connection.Connection;
24 | import com.mpush.api.protocol.Command;
25 | import com.mpush.api.protocol.Packet;
26 | import com.mpush.api.Constants;
27 |
28 | /**
29 | * Created by ohun on 2015/12/30.
30 | *
31 | * @author ohun@live.cn (夜色)
32 | */
33 | public final class PushMessage extends BaseMessage {
34 |
35 | public byte[] content;
36 |
37 | public PushMessage(byte[] content, Connection connection) {
38 | super(new Packet(Command.PUSH, genSessionId()), connection);
39 | this.content = content;
40 | }
41 |
42 | public PushMessage(Packet packet, Connection connection) {
43 | super(packet, connection);
44 | }
45 |
46 | @Override
47 | public void decode(byte[] body) {
48 | content = body;
49 | }
50 |
51 | @Override
52 | public byte[] encode() {
53 | return content;
54 | }
55 |
56 | public boolean autoAck() {
57 | return packet.hasFlag(Packet.FLAG_AUTO_ACK);
58 | }
59 |
60 | public boolean bizAck() {
61 | return packet.hasFlag(Packet.FLAG_BIZ_ACK);
62 | }
63 |
64 | public PushMessage addFlag(byte flag) {
65 | packet.addFlag(flag);
66 | return this;
67 | }
68 |
69 | @Override
70 | public String toString() {
71 | return "PushMessage{" +
72 | "content='" + content.length + '\'' +
73 | '}';
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/security/AesCipher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.security;
21 |
22 |
23 |
24 | import com.mpush.api.connection.Cipher;
25 | import com.mpush.util.crypto.AESUtils;
26 |
27 | /**
28 | * Created by ohun on 2015/12/28.
29 | *
30 | * @author ohun@live.cn (夜色)
31 | */
32 | public final class AesCipher implements Cipher {
33 | public final byte[] key;
34 | public final byte[] iv;
35 |
36 | public AesCipher(byte[] key, byte[] iv) {
37 | this.key = key;
38 | this.iv = iv;
39 | }
40 |
41 | @Override
42 | public byte[] decrypt(byte[] data) {
43 | return AESUtils.decrypt(data, key, iv);
44 | }
45 |
46 | @Override
47 | public byte[] encrypt(byte[] data) {
48 | return AESUtils.encrypt(data, key, iv);
49 | }
50 |
51 | @Override
52 | public String toString() {
53 | return toString(key) + ',' + toString(iv);
54 | }
55 |
56 | public String toString(byte[] a) {
57 | StringBuilder b = new StringBuilder();
58 | for (int i = 0; i < a.length; i++) {
59 | if (i != 0) b.append('|');
60 | b.append(a[i]);
61 | }
62 | return b.toString();
63 | }
64 |
65 | public static byte[] toArray(String str) {
66 | String[] a = str.split("\\|");
67 | if (a.length != CipherBox.INSTANCE.getAesKeyLength()) {
68 | return null;
69 | }
70 | byte[] bytes = new byte[a.length];
71 | for (int i = 0; i < a.length; i++) {
72 | bytes[i] = Byte.parseByte(a[i]);
73 | }
74 | return bytes;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/security/CipherBox.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.security;
21 |
22 |
23 |
24 | import com.mpush.client.ClientConfig;
25 | import com.mpush.util.crypto.RSAUtils;
26 |
27 | import java.security.SecureRandom;
28 | import java.security.interfaces.RSAPublicKey;
29 |
30 | /**
31 | * Created by ohun on 2015/12/24.
32 | *
33 | * @author ohun@live.cn (夜色)
34 | */
35 | public final class CipherBox {
36 | public int aesKeyLength = ClientConfig.I.getAesKeyLength();
37 | public static final CipherBox INSTANCE = new CipherBox();
38 | private SecureRandom random = new SecureRandom();
39 | private RSAPublicKey publicKey;
40 |
41 |
42 | public RSAPublicKey getPublicKey() {
43 | if (publicKey == null) {
44 | String key = ClientConfig.I.getPublicKey();
45 | try {
46 | publicKey = (RSAPublicKey) RSAUtils.decodePublicKey(key);
47 | } catch (Exception e) {
48 | throw new RuntimeException("load public key ex, key=" + key, e);
49 | }
50 | }
51 | return publicKey;
52 | }
53 |
54 | public byte[] randomAESKey() {
55 | byte[] bytes = new byte[aesKeyLength];
56 | random.nextBytes(bytes);
57 | return bytes;
58 | }
59 |
60 | public byte[] randomAESIV() {
61 | byte[] bytes = new byte[aesKeyLength];
62 | random.nextBytes(bytes);
63 | return bytes;
64 | }
65 |
66 | public byte[] mixKey(byte[] clientKey, byte[] serverKey) {
67 | byte[] sessionKey = new byte[aesKeyLength];
68 | for (int i = 0; i < aesKeyLength; i++) {
69 | byte a = clientKey[i];
70 | byte b = serverKey[i];
71 | int sum = Math.abs(a + b);
72 | int c = (sum % 2 == 0) ? a ^ b : b ^ a;
73 | sessionKey[i] = (byte) c;
74 | }
75 | return sessionKey;
76 | }
77 |
78 | public int getAesKeyLength() {
79 | return aesKeyLength;
80 | }
81 |
82 | public RsaCipher getRsaCipher() {
83 | return new RsaCipher(getPublicKey());
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/security/RsaCipher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.security;
21 |
22 |
23 |
24 | import com.mpush.api.connection.Cipher;
25 | import com.mpush.util.crypto.RSAUtils;
26 |
27 | import java.security.interfaces.RSAPublicKey;
28 |
29 | /**
30 | * Created by ohun on 2015/12/28.
31 | *
32 | * @author ohun@live.cn (夜色)
33 | */
34 | public final class RsaCipher implements Cipher {
35 |
36 | private final RSAPublicKey publicKey;
37 |
38 | public RsaCipher(RSAPublicKey publicKey) {
39 | this.publicKey = publicKey;
40 | }
41 |
42 | @Override
43 | public byte[] decrypt(byte[] data) {
44 | throw new UnsupportedOperationException();
45 | }
46 |
47 | @Override
48 | public byte[] encrypt(byte[] data) {
49 | return RSAUtils.encryptByPublicKey(data, publicKey);
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return "RsaCipher [publicKey=" + new String(publicKey.getEncoded()) + "]";
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/session/FileSessionStorage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.session;
21 |
22 |
23 | import com.mpush.api.connection.SessionStorage;
24 | import com.mpush.util.IOUtils;
25 | import com.mpush.api.Constants;
26 | import com.mpush.client.ClientConfig;
27 |
28 | import java.io.*;
29 |
30 | /**
31 | * Created by ohun on 2016/1/25.
32 | *
33 | * @author ohun@live.cn (夜色)
34 | */
35 | public final class FileSessionStorage implements SessionStorage {
36 | private final String rootDir;
37 | private final String fileName = "token.dat";
38 |
39 | public FileSessionStorage(String rootDir) {
40 | this.rootDir = rootDir;
41 | }
42 |
43 | @Override
44 | public void saveSession(String sessionContext) {
45 | File file = new File(rootDir, fileName);
46 | FileOutputStream out = null;
47 | try {
48 | if (!file.exists()) file.getParentFile().mkdirs();
49 | else if (file.canWrite()) file.delete();
50 | out = new FileOutputStream(file);
51 | out.write(sessionContext.getBytes(Constants.UTF_8));
52 | } catch (Exception e) {
53 | ClientConfig.I.getLogger().e(e, "save session context ex, session=%s, rootDir=%s"
54 | , sessionContext, rootDir);
55 | } finally {
56 | IOUtils.close(out);
57 | }
58 | }
59 |
60 | @Override
61 | public String getSession() {
62 | File file = new File(rootDir, fileName);
63 | if (!file.exists()) return null;
64 | InputStream in = null;
65 | try {
66 | in = new FileInputStream(file);
67 | byte[] bytes = new byte[in.available()];
68 | if (bytes.length > 0) {
69 | in.read(bytes);
70 | return new String(bytes, Constants.UTF_8);
71 | }
72 | in.close();
73 | } catch (Exception e) {
74 | ClientConfig.I.getLogger().e(e, "get session context ex,rootDir=%s", rootDir);
75 | } finally {
76 | IOUtils.close(in);
77 | }
78 | return null;
79 | }
80 |
81 | @Override
82 | public void clearSession() {
83 | File file = new File(rootDir, fileName);
84 | if (file.exists() && file.canWrite()) {
85 | file.delete();
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/session/PersistentSession.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.session;
21 |
22 |
23 | import com.mpush.api.connection.Cipher;
24 | import com.mpush.security.AesCipher;
25 | import com.mpush.util.Strings;
26 |
27 | /**
28 | * Created by ohun on 2016/1/25.
29 | *
30 | * @author ohun@live.cn (夜色)
31 | */
32 | public final class PersistentSession {
33 | public String sessionId;
34 | public long expireTime;
35 | public Cipher cipher;
36 |
37 | public boolean isExpired() {
38 | return expireTime < System.currentTimeMillis();
39 | }
40 |
41 | public static String encode(PersistentSession session) {
42 | return session.sessionId
43 | + "," + session.expireTime
44 | + "," + session.cipher.toString();
45 | }
46 |
47 | public static PersistentSession decode(String value) {
48 | String[] array = value.split(",");
49 | if (array.length != 4) return null;
50 | PersistentSession session = new PersistentSession();
51 | session.sessionId = array[0];
52 | session.expireTime = Strings.toLong(array[1], 0);
53 | byte[] key = AesCipher.toArray(array[2]);
54 | byte[] iv = AesCipher.toArray(array[3]);
55 | if (key == null || iv == null) return null;
56 | session.cipher = new AesCipher(key, iv);
57 | return session;
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return "PersistentSession{" +
63 | "sessionId='" + sessionId + '\'' +
64 | ", expireTime=" + expireTime +
65 | ", cipher=" + cipher +
66 | '}';
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/ByteBuf.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util;
21 |
22 |
23 | import java.nio.*;
24 |
25 | /**
26 | * Created by ohun on 2016/1/21.
27 | *
28 | * @author ohun@live.cn (夜色)
29 | */
30 | public final class ByteBuf {
31 | private ByteBuffer tmpNioBuf;
32 |
33 | public static ByteBuf allocate(int capacity) {
34 | ByteBuf buffer = new ByteBuf();
35 | buffer.tmpNioBuf = ByteBuffer.allocate(capacity);
36 | return buffer;
37 | }
38 |
39 | public static ByteBuf allocateDirect(int capacity) {
40 | ByteBuf buffer = new ByteBuf();
41 | buffer.tmpNioBuf = ByteBuffer.allocateDirect(capacity);
42 | return buffer;
43 | }
44 |
45 | public static ByteBuf wrap(byte[] array) {
46 | ByteBuf buffer = new ByteBuf();
47 | buffer.tmpNioBuf = ByteBuffer.wrap(array);
48 | return buffer;
49 | }
50 |
51 | public byte[] getArray() {
52 | tmpNioBuf.flip();
53 | byte[] array = new byte[tmpNioBuf.remaining()];
54 | tmpNioBuf.get(array);
55 | tmpNioBuf.compact();
56 | return array;
57 | }
58 |
59 | public ByteBuf get(byte[] array) {
60 | tmpNioBuf.get(array);
61 | return this;
62 | }
63 |
64 | public byte get() {
65 | return tmpNioBuf.get();
66 | }
67 |
68 | public ByteBuf put(byte b) {
69 | checkCapacity(1);
70 | tmpNioBuf.put(b);
71 | return this;
72 | }
73 |
74 | public short getShort() {
75 | return tmpNioBuf.getShort();
76 | }
77 |
78 | public ByteBuf putShort(int value) {
79 | checkCapacity(2);
80 | tmpNioBuf.putShort((short) value);
81 | return this;
82 | }
83 |
84 | public int getInt() {
85 | return tmpNioBuf.getInt();
86 | }
87 |
88 | public ByteBuf putInt(int value) {
89 | checkCapacity(4);
90 | tmpNioBuf.putInt(value);
91 | return this;
92 | }
93 |
94 | public long getLong() {
95 | return tmpNioBuf.getLong();
96 | }
97 |
98 | public ByteBuf putLong(long value) {
99 | checkCapacity(8);
100 | tmpNioBuf.putLong(value);
101 | return this;
102 | }
103 |
104 | public ByteBuf put(byte[] value) {
105 | checkCapacity(value.length);
106 | tmpNioBuf.put(value);
107 | return this;
108 | }
109 |
110 | public ByteBuf checkCapacity(int minWritableBytes) {
111 | int remaining = tmpNioBuf.remaining();
112 | if (remaining < minWritableBytes) {
113 | int newCapacity = newCapacity(tmpNioBuf.capacity() + minWritableBytes);
114 | ByteBuffer newBuffer = tmpNioBuf.isDirect() ? ByteBuffer.allocateDirect(newCapacity) : ByteBuffer.allocate(newCapacity);
115 | tmpNioBuf.flip();
116 | newBuffer.put(tmpNioBuf);
117 | tmpNioBuf = newBuffer;
118 | }
119 | return this;
120 | }
121 |
122 | private int newCapacity(int minNewCapacity) {
123 | int newCapacity = 64;
124 | while (newCapacity < minNewCapacity) {
125 | newCapacity <<= 1;
126 | }
127 | return newCapacity;
128 | }
129 |
130 | public ByteBuffer nioBuffer() {
131 | return tmpNioBuf;
132 | }
133 |
134 | public ByteBuf clear() {
135 | tmpNioBuf.clear();
136 | return this;
137 | }
138 |
139 | public ByteBuf flip() {
140 | tmpNioBuf.flip();
141 | return this;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/DefaultLogger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util;
21 |
22 |
23 | import com.mpush.api.Logger;
24 |
25 | import java.text.DateFormat;
26 | import java.text.SimpleDateFormat;
27 | import java.util.Date;
28 |
29 | /**
30 | * Created by ohun on 2016/1/25.
31 | *
32 | * @author ohun@live.cn (夜色)
33 | */
34 | public final class DefaultLogger implements Logger {
35 | private static final String TAG = "[mpush] ";
36 | private final DateFormat format = new SimpleDateFormat("HH:mm:ss.SSS");
37 |
38 | private boolean enable = false;
39 |
40 | @Override
41 | public void enable(boolean enabled) {
42 | this.enable = enabled;
43 | }
44 |
45 | @Override
46 | public void d(String s, Object... args) {
47 | if (enable) {
48 | System.out.printf(format.format(new Date()) + " [D] " + TAG + s + '\n', args);
49 | }
50 | }
51 |
52 | @Override
53 | public void i(String s, Object... args) {
54 | if (enable) {
55 | System.out.printf(format.format(new Date()) + " [I] " + TAG + s + '\n', args);
56 | }
57 | }
58 |
59 | @Override
60 | public void w(String s, Object... args) {
61 | if (enable) {
62 | System.err.printf(format.format(new Date()) + " [W] " + TAG + s + '\n', args);
63 | }
64 | }
65 |
66 | @Override
67 | public void e(Throwable e, String s, Object... args) {
68 | if (enable) {
69 | System.err.printf(format.format(new Date()) + " [E] " + TAG + s + '\n', args);
70 | e.printStackTrace();
71 | }
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/IOUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util;
21 |
22 |
23 |
24 | import com.mpush.api.Constants;
25 |
26 | import java.io.ByteArrayInputStream;
27 | import java.io.ByteArrayOutputStream;
28 | import java.io.Closeable;
29 | import java.io.IOException;
30 | import java.util.zip.DeflaterOutputStream;
31 | import java.util.zip.InflaterInputStream;
32 |
33 | /**
34 | * Created by ohun on 2015/12/25.
35 | *
36 | * @author ohun@live.cn (夜色)
37 | */
38 | public final class IOUtils {
39 |
40 | public static void close(Closeable closeable) {
41 | if (closeable != null) {
42 | try {
43 | closeable.close();
44 | } catch (Exception e) {
45 | }
46 | }
47 | }
48 |
49 | public static byte[] compress(byte[] data) {
50 | ByteArrayOutputStream byteStream = new ByteArrayOutputStream(data.length / 4);
51 | DeflaterOutputStream zipOut = new DeflaterOutputStream(byteStream);
52 | try {
53 | zipOut.write(data);
54 | zipOut.finish();
55 | zipOut.close();
56 | } catch (IOException e) {
57 | return Constants.EMPTY_BYTES;
58 | } finally {
59 | close(zipOut);
60 | }
61 | return byteStream.toByteArray();
62 | }
63 |
64 | public static byte[] uncompress(byte[] data) {
65 | InflaterInputStream in = new InflaterInputStream(new ByteArrayInputStream(data));
66 | ByteArrayOutputStream out = new ByteArrayOutputStream(data.length * 4);
67 | byte[] buffer = new byte[1024];
68 | int length;
69 | try {
70 | while ((length = in.read(buffer)) != -1) {
71 | out.write(buffer, 0, length);
72 | }
73 | } catch (IOException e) {
74 | return Constants.EMPTY_BYTES;
75 | } finally {
76 | close(in);
77 | }
78 | return out.toByteArray();
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/MPUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util;
21 |
22 |
23 | import java.net.InetAddress;
24 | import java.net.UnknownHostException;
25 | import java.util.HashMap;
26 | import java.util.Map;
27 | import java.util.regex.Pattern;
28 |
29 | /**
30 | * Created by ohun on 2016/1/25.
31 | *
32 | * @author ohun@live.cn (夜色)
33 | */
34 | public final class MPUtils {
35 |
36 | /**
37 | * Quick and dirty pattern to differentiate IP addresses from hostnames. This is an approximation
38 | * of Android's private InetAddress#isNumeric API.
39 | *
40 | *
This matches IPv6 addresses as a hex string containing at least one colon, and possibly
41 | * including dots after the first colon. It matches IPv4 addresses as strings containing only
42 | * decimal digits and dots. This pattern matches strings like "a:.23" and "54" that are neither IP
43 | * addresses nor hostnames; they will be verified as IP addresses (which is a more strict
44 | * verification).
45 | */
46 | private static final Pattern VERIFY_AS_IP_ADDRESS = Pattern.compile(
47 | "([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");
48 |
49 | public static String parseHost2Ip(String host) {
50 | InetAddress ia = null;
51 | try {
52 | ia = InetAddress.getByName(host);
53 | } catch (UnknownHostException e) {
54 | }
55 | if (ia != null) {
56 | return ia.getHostAddress();
57 | }
58 | return host;
59 | }
60 |
61 | public static String headerToString(Map headers) {
62 | if (headers != null && headers.size() > 0) {
63 | StringBuilder sb = new StringBuilder(headers.size() * 64);
64 | for (Map.Entry entry : headers.entrySet()) {
65 | sb.append(entry.getKey())
66 | .append(':')
67 | .append(entry.getValue()).append('\n');
68 | }
69 | return sb.toString();
70 | }
71 | return null;
72 | }
73 |
74 |
75 | public static Map headerFromString(String headersString) {
76 | if (headersString == null) return null;
77 | Map headers = new HashMap<>();
78 | int L = headersString.length();
79 | String name, value = null;
80 | for (int i = 0, start = 0; i < L; i++) {
81 | char c = headersString.charAt(i);
82 | if (c != '\n') continue;
83 | if (start >= L - 1) break;
84 | String header = headersString.substring(start, i);
85 | start = i + 1;
86 | int index = header.indexOf(':');
87 | if (index <= 0) continue;
88 | name = header.substring(0, index);
89 | if (index < header.length() - 1) {
90 | value = header.substring(index + 1);
91 | }
92 | headers.put(name, value);
93 | }
94 | return headers;
95 | }
96 |
97 | /**
98 | * Returns true if {@code host} is not a host name and might be an IP address.
99 | */
100 | public static boolean verifyAsIpAddress(String host) {
101 | return VERIFY_AS_IP_ADDRESS.matcher(host).matches();
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/Strings.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util;
21 |
22 |
23 | /**
24 | * Created by ohun on 2015/12/23.
25 | *
26 | * @author ohun@live.cn (夜色)
27 | */
28 | public final class Strings {
29 | public static final String EMPTY = "";
30 |
31 | public static boolean isBlank(CharSequence text) {
32 | if (text == null || text.length() == 0) return true;
33 | for (int i = 0, L = text.length(); i < L; i++) {
34 | if (!Character.isWhitespace(text.charAt(i))) return false;
35 | }
36 | return true;
37 | }
38 |
39 | public static long toLong(String text, long defaultVal) {
40 | try {
41 | return Long.parseLong(text);
42 | } catch (NumberFormatException e) {
43 | }
44 | return defaultVal;
45 | }
46 |
47 | public static int toInt(String text, int defaultVal) {
48 | try {
49 | return Integer.parseInt(text);
50 | } catch (NumberFormatException e) {
51 | }
52 | return defaultVal;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/crypto/AESUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util.crypto;
21 |
22 |
23 |
24 | import com.mpush.client.ClientConfig;
25 | import com.mpush.api.Constants;
26 |
27 | import javax.crypto.Cipher;
28 | import javax.crypto.spec.IvParameterSpec;
29 | import javax.crypto.spec.SecretKeySpec;
30 |
31 | /**
32 | * Created by ohun on 2015/12/25.
33 | *
34 | * @author ohun@live.cn (夜色)
35 | */
36 | public final class AESUtils {
37 | public static final String KEY_ALGORITHM = "AES";
38 | public static final String KEY_ALGORITHM_PADDING = "AES/CBC/PKCS5Padding";
39 |
40 |
41 | public static byte[] encrypt(byte[] data, byte[] encryptKey, byte[] iv) {
42 | IvParameterSpec zeroIv = new IvParameterSpec(iv);
43 | SecretKeySpec key = new SecretKeySpec(encryptKey, KEY_ALGORITHM);
44 | try {
45 | Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_PADDING);
46 | cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
47 | return cipher.doFinal(data);
48 | } catch (Exception e) {
49 | ClientConfig.I.getLogger().e(e, "encrypt ex, decryptKey=%s", encryptKey);
50 | }
51 | return Constants.EMPTY_BYTES;
52 | }
53 |
54 | public static byte[] decrypt(byte[] data, byte[] decryptKey, byte[] iv) {
55 | IvParameterSpec zeroIv = new IvParameterSpec(iv);
56 | SecretKeySpec key = new SecretKeySpec(decryptKey, KEY_ALGORITHM);
57 | try {
58 | Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_PADDING);
59 | cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
60 | return cipher.doFinal(data);
61 | } catch (Exception e) {
62 | ClientConfig.I.getLogger().e(e, "decrypt ex, decryptKey=%s", decryptKey);
63 | }
64 | return Constants.EMPTY_BYTES;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/crypto/Base64Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util.crypto;
21 |
22 |
23 |
24 | import com.mpush.api.Constants;
25 |
26 | import java.io.*;
27 |
28 | /**
29 | *
30 | * BASE64编码解码工具包
31 | *
32 | *
33 | * 依赖javabase64-1.3.1.jar
34 | *
35 | */
36 | public class Base64Utils {
37 |
38 | /**
39 | * 文件读取缓冲区大小
40 | */
41 | private static final int CACHE_SIZE = 1024;
42 |
43 | /**
44 | *
45 | * BASE64字符串解码为二进制数据
46 | *
47 | *
48 | * @param base64 xxx
49 | * @return return
50 | * @throws Exception xxx
51 | */
52 | public static byte[] decode(String base64) throws Exception {
53 | return Base64.getDecoder().decode(base64);
54 | }
55 |
56 | /**
57 | *
58 | * 二进制数据编码为BASE64字符串
59 | *
60 | *
61 | * @param bytes xxx
62 | * @return return
63 | * @throws Exception xxx
64 | */
65 | public static String encode(byte[] bytes) throws Exception {
66 | return new String(Base64.getEncoder().encode(bytes), Constants.UTF_8);
67 | }
68 |
69 | /**
70 | *
71 | * 将文件编码为BASE64字符串
72 | *
73 | *
74 | * 大文件慎用,可能会导致内存溢出
75 | *
76 | *
77 | * @param filePath 文件绝对路径
78 | * @return return xxxx
79 | * @throws Exception xxxx
80 | */
81 | public static String encodeFile(String filePath) throws Exception {
82 | byte[] bytes = fileToByte(filePath);
83 | return encode(bytes);
84 | }
85 |
86 | /**
87 | *
88 | * BASE64字符串转回文件
89 | *
90 | *
91 | * @param filePath 文件绝对路径
92 | * @param base64 编码字符串
93 | * @throws Exception xxxx
94 | */
95 | public static void decodeToFile(String filePath, String base64) throws Exception {
96 | byte[] bytes = decode(base64);
97 | byteArrayToFile(bytes, filePath);
98 | }
99 |
100 | /**
101 | *
102 | * 文件转换为二进制数组
103 | *
104 | *
105 | * @param filePath 文件路径
106 | * @return return xxxx
107 | * @throws Exception xxxx
108 | */
109 | public static byte[] fileToByte(String filePath) throws Exception {
110 | byte[] data = new byte[0];
111 | File file = new File(filePath);
112 | if (file.exists()) {
113 | FileInputStream in = new FileInputStream(file);
114 | ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
115 | byte[] cache = new byte[CACHE_SIZE];
116 | int nRead = 0;
117 | while ((nRead = in.read(cache)) != -1) {
118 | out.write(cache, 0, nRead);
119 | out.flush();
120 | }
121 | out.close();
122 | in.close();
123 | data = out.toByteArray();
124 | }
125 | return data;
126 | }
127 |
128 | /**
129 | *
130 | * 二进制数据写文件
131 | *
132 | *
133 | * @param bytes 二进制数据
134 | * @param filePath 文件生成目录
135 | * @throws Exception Exception
136 | */
137 | public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
138 | InputStream in = new ByteArrayInputStream(bytes);
139 | File destFile = new File(filePath);
140 | if (!destFile.getParentFile().exists()) {
141 | destFile.getParentFile().mkdirs();
142 | }
143 | destFile.createNewFile();
144 | OutputStream out = new FileOutputStream(destFile);
145 | byte[] cache = new byte[CACHE_SIZE];
146 | int nRead = 0;
147 | while ((nRead = in.read(cache)) != -1) {
148 | out.write(cache, 0, nRead);
149 | out.flush();
150 | }
151 | out.close();
152 | in.close();
153 | }
154 | }
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/crypto/MD5Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util.crypto;
21 |
22 |
23 |
24 | import com.mpush.util.IOUtils;
25 | import com.mpush.api.Constants;
26 | import com.mpush.util.Strings;
27 |
28 | import javax.crypto.Mac;
29 | import javax.crypto.spec.SecretKeySpec;
30 | import java.io.File;
31 | import java.io.FileInputStream;
32 | import java.io.InputStream;
33 | import java.security.MessageDigest;
34 |
35 | /**
36 | * Created by ohun on 2015/12/25.
37 | *
38 | * @author ohun@live.cn (夜色)
39 | */
40 | public final class MD5Utils {
41 | public static String encrypt(File file) {
42 | InputStream in = null;
43 | try {
44 | MessageDigest digest = MessageDigest.getInstance("MD5");
45 | in = new FileInputStream(file);
46 | byte[] buffer = new byte[10240];//10k
47 | int readLen;
48 | while ((readLen = in.read(buffer)) != -1) {
49 | digest.update(buffer, 0, readLen);
50 | }
51 | return toHex(digest.digest());
52 | } catch (Exception e) {
53 | return Strings.EMPTY;
54 | } finally {
55 | IOUtils.close(in);
56 | }
57 | }
58 |
59 | public static String encrypt(String text) {
60 | try {
61 | MessageDigest digest = MessageDigest.getInstance("MD5");
62 | digest.update(text.getBytes(Constants.UTF_8));
63 | return toHex(digest.digest());
64 | } catch (Exception e) {
65 | return Strings.EMPTY;
66 | }
67 | }
68 |
69 | public static String encrypt(byte[] bytes) {
70 | try {
71 | MessageDigest digest = MessageDigest.getInstance("MD5");
72 | digest.update(bytes);
73 | return toHex(digest.digest());
74 | } catch (Exception e) {
75 | return Strings.EMPTY;
76 | }
77 | }
78 |
79 | private static String toHex(byte[] bytes) {
80 | StringBuffer buffer = new StringBuffer(bytes.length * 2);
81 |
82 | for (int i = 0; i < bytes.length; ++i) {
83 | buffer.append(Character.forDigit((bytes[i] & 240) >> 4, 16));
84 | buffer.append(Character.forDigit(bytes[i] & 15, 16));
85 | }
86 |
87 | return buffer.toString();
88 | }
89 |
90 | /**
91 | * HmacSHA1 加密
92 | *
93 | * @param data xxx
94 | * @param encryptKey xxx
95 | * @return xxxx
96 | */
97 | public static String hmacSha1(String data, String encryptKey) {
98 | final String HMAC_SHA1 = "HmacSHA1";
99 | SecretKeySpec signingKey = new SecretKeySpec(encryptKey.getBytes(Constants.UTF_8), HMAC_SHA1);
100 | try {
101 | Mac mac = Mac.getInstance(HMAC_SHA1);
102 | mac.init(signingKey);
103 | mac.update(data.getBytes(Constants.UTF_8));
104 | return toHex(mac.doFinal());
105 | } catch (Exception e) {
106 | return Strings.EMPTY;
107 | }
108 | }
109 |
110 | /**
111 | * HmacSHA1 加密
112 | *
113 | * @param data xxx
114 | * @return xxx
115 | */
116 | public static String sha1(String data) {
117 | try {
118 | MessageDigest digest = MessageDigest.getInstance("SHA-1");
119 | return toHex(digest.digest(data.getBytes(Constants.UTF_8)));
120 | } catch (Exception e) {
121 | return Strings.EMPTY;
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/thread/EventLock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util.thread;
21 |
22 |
23 | import java.util.concurrent.TimeUnit;
24 | import java.util.concurrent.locks.Condition;
25 | import java.util.concurrent.locks.ReentrantLock;
26 |
27 | /**
28 | * Created by ohun on 2016/1/17.
29 | *
30 | * @author ohun@live.cn (夜色)
31 | */
32 | public final class EventLock {
33 | private final ReentrantLock lock;
34 | private final Condition cond;
35 |
36 | public EventLock() {
37 | lock = new ReentrantLock();
38 | cond = lock.newCondition();
39 | }
40 |
41 | public void lock() {
42 | lock.lock();
43 | }
44 |
45 | public void unlock() {
46 | lock.unlock();
47 | }
48 |
49 | public void signal() {
50 | cond.signal();
51 | }
52 |
53 | public void signalAll() {
54 | cond.signalAll();
55 | }
56 |
57 | public void broadcast() {
58 | lock.lock();
59 | cond.signalAll();
60 | lock.unlock();
61 | }
62 |
63 | public boolean await(long timeout) {
64 | lock.lock();
65 | try {
66 | cond.awaitNanos(TimeUnit.MILLISECONDS.toNanos(timeout));
67 | } catch (InterruptedException e) {
68 | return true;
69 | } finally {
70 | lock.unlock();
71 | }
72 | return false;
73 | }
74 |
75 | public boolean await() {
76 | lock.lock();
77 | try {
78 | cond.await();
79 | } catch (InterruptedException e) {
80 | return true;
81 | } finally {
82 | lock.unlock();
83 | }
84 | return false;
85 | }
86 |
87 | public ReentrantLock getLock() {
88 | return lock;
89 | }
90 |
91 | public Condition getCond() {
92 | return cond;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/thread/ExecutorManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util.thread;
21 |
22 |
23 | import com.mpush.client.ClientConfig;
24 |
25 | import java.util.concurrent.LinkedBlockingQueue;
26 | import java.util.concurrent.RejectedExecutionHandler;
27 | import java.util.concurrent.ScheduledExecutorService;
28 | import java.util.concurrent.ScheduledThreadPoolExecutor;
29 | import java.util.concurrent.ThreadPoolExecutor;
30 | import java.util.concurrent.TimeUnit;
31 |
32 | /**
33 | * Created by ohun on 2016/1/23.
34 | *
35 | * @author ohun@live.cn (夜色)
36 | */
37 | public final class ExecutorManager {
38 | public static final String THREAD_NAME_PREFIX = "mp-client-";
39 | public static final String WRITE_THREAD_NAME = THREAD_NAME_PREFIX + "write-t";
40 | public static final String READ_THREAD_NAME = THREAD_NAME_PREFIX + "read-t";
41 | public static final String DISPATCH_THREAD_NAME = THREAD_NAME_PREFIX + "dispatch-t";
42 | public static final String START_THREAD_NAME = THREAD_NAME_PREFIX + "start-t";
43 | public static final String TIMER_THREAD_NAME = THREAD_NAME_PREFIX + "timer-t";
44 | public static final ExecutorManager INSTANCE = new ExecutorManager();
45 | private ThreadPoolExecutor writeThread;
46 | private ThreadPoolExecutor dispatchThread;
47 | private ScheduledExecutorService timerThread;
48 |
49 | public ThreadPoolExecutor getWriteThread() {
50 | if (writeThread == null || writeThread.isShutdown()) {
51 | writeThread = new ThreadPoolExecutor(1, 1,
52 | 0L, TimeUnit.MILLISECONDS,
53 | new LinkedBlockingQueue(100),
54 | new NamedThreadFactory(WRITE_THREAD_NAME),
55 | new RejectedHandler());
56 | }
57 | return writeThread;
58 | }
59 |
60 | public ThreadPoolExecutor getDispatchThread() {
61 | if (dispatchThread == null || dispatchThread.isShutdown()) {
62 | dispatchThread = new ThreadPoolExecutor(2, 4,
63 | 1L, TimeUnit.SECONDS,
64 | new LinkedBlockingQueue(100),
65 | new NamedThreadFactory(DISPATCH_THREAD_NAME),
66 | new RejectedHandler());
67 | }
68 | return dispatchThread;
69 | }
70 |
71 | public ScheduledExecutorService getTimerThread() {
72 | if (timerThread == null || timerThread.isShutdown()) {
73 | timerThread = new ScheduledThreadPoolExecutor(1,
74 | new NamedThreadFactory(TIMER_THREAD_NAME),
75 | new RejectedHandler());
76 | }
77 | return timerThread;
78 | }
79 |
80 | public synchronized void shutdown() {
81 | if (writeThread != null) {
82 | writeThread.shutdownNow();
83 | writeThread = null;
84 | }
85 | if (dispatchThread != null) {
86 | dispatchThread.shutdownNow();
87 | dispatchThread = null;
88 | }
89 | if (timerThread != null) {
90 | timerThread.shutdownNow();
91 | timerThread = null;
92 | }
93 | }
94 |
95 | public static boolean isMPThread() {
96 | return Thread.currentThread().getName().startsWith(THREAD_NAME_PREFIX);
97 | }
98 |
99 | private static class RejectedHandler implements RejectedExecutionHandler {
100 |
101 | @Override
102 | public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
103 | ClientConfig.I.getLogger().w("a task was rejected r=%s", r);
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/com/mpush/util/thread/NamedThreadFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.util.thread;
21 |
22 |
23 | import java.util.concurrent.ThreadFactory;
24 | import java.util.concurrent.atomic.AtomicInteger;
25 |
26 | /**
27 | * Created by xiaoxu.yxx on 2015/7/19.
28 | */
29 | public final class NamedThreadFactory implements ThreadFactory {
30 | protected final AtomicInteger threadNumber = new AtomicInteger(1);
31 | protected final String namePrefix;
32 | protected final ThreadGroup group;
33 |
34 | public NamedThreadFactory(final String namePrefix) {
35 | this.namePrefix = namePrefix;
36 | this.group = Thread.currentThread().getThreadGroup();
37 | }
38 |
39 | public Thread newThread(String name, Runnable r) {
40 | return new Thread(r, name);
41 | }
42 |
43 | @Override
44 | public Thread newThread(Runnable r) {
45 | Thread t = newThread(namePrefix + threadNumber.getAndIncrement(), r);
46 | if (t.isDaemon())
47 | t.setDaemon(false);
48 | return t;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/test/java/com/mpush/client/MPushClientTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2015-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Contributors:
17 | * ohun@live.cn (夜色)
18 | */
19 |
20 | package com.mpush.client;
21 |
22 |
23 | import com.mpush.api.Client;
24 | import com.mpush.api.ClientListener;
25 | import com.mpush.util.DefaultLogger;
26 |
27 | import java.util.concurrent.Executors;
28 | import java.util.concurrent.ScheduledExecutorService;
29 | import java.util.concurrent.TimeUnit;
30 |
31 | /**
32 | * Created by ohun on 2016/1/25.
33 | *
34 | * @author ohun@live.cn (夜色)
35 | */
36 | public class MPushClientTest {
37 | private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCghPCWCobG8nTD24juwSVataW7iViRxcTkey/B792VZEhuHjQvA3cAJgx2Lv8GnX8NIoShZtoCg3Cx6ecs+VEPD2fBcg2L4JK7xldGpOJ3ONEAyVsLOttXZtNXvyDZRijiErQALMTorcgi79M5uVX9/jMv2Ggb2XAeZhlLD28fHwIDAQAB";
38 | private static final String allocServer = "http://103.60.220.145:9999/";
39 |
40 | public static void main(String[] args) throws Exception {
41 | int count = 1;
42 | String serverHost = "127.0.0.1";
43 | int sleep = 1000;
44 |
45 | if (args != null && args.length > 0) {
46 | count = Integer.parseInt(args[0]);
47 | if (args.length > 1) {
48 | serverHost = args[1];
49 | }
50 | if (args.length > 2) {
51 | sleep = Integer.parseInt(args[1]);
52 | }
53 | }
54 |
55 | ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
56 | ClientListener listener = new L(scheduledExecutor);
57 | Client client = null;
58 | String cacheDir = MPushClientTest.class.getResource("/").getFile();
59 | for (int i = 0; i < count; i++) {
60 | client = ClientConfig
61 | .build()
62 | .setPublicKey(publicKey)
63 | //.setAllotServer(allocServer)
64 | .setServerHost(serverHost)
65 | .setServerPort(3000)
66 | .setDeviceId("deviceId-test" + i)
67 | .setOsName("android")
68 | .setOsVersion("6.0")
69 | .setClientVersion("2.0")
70 | .setUserId("user-" + i)
71 | .setTags("tag-" + i)
72 | .setSessionStorageDir(cacheDir + i)
73 | .setLogger(new DefaultLogger())
74 | .setLogEnabled(true)
75 | .setEnableHttpProxy(true)
76 | .setClientListener(listener)
77 | .create();
78 | client.start();
79 | Thread.sleep(sleep);
80 | }
81 | }
82 |
83 | public static class L implements ClientListener {
84 | private final ScheduledExecutorService scheduledExecutor;
85 | boolean flag = true;
86 |
87 | public L(ScheduledExecutorService scheduledExecutor) {
88 | this.scheduledExecutor = scheduledExecutor;
89 | }
90 |
91 | @Override
92 | public void onConnected(Client client) {
93 | flag = true;
94 | }
95 |
96 | @Override
97 | public void onDisConnected(Client client) {
98 | flag = false;
99 | }
100 |
101 | @Override
102 | public void onHandshakeOk(final Client client, final int heartbeat) {
103 | scheduledExecutor.scheduleAtFixedRate(new Runnable() {
104 | @Override
105 | public void run() {
106 | client.healthCheck();
107 | }
108 | }, 10, 10, TimeUnit.SECONDS);
109 |
110 | //client.push(PushContext.build("test"));
111 |
112 | }
113 |
114 | @Override
115 | public void onReceivePush(Client client, byte[] content, int messageId) {
116 | if (messageId > 0) client.ack(messageId);
117 | }
118 |
119 | @Override
120 | public void onKickUser(String deviceId, String userId) {
121 |
122 | }
123 |
124 | @Override
125 | public void onBind(boolean success, String userId) {
126 |
127 | }
128 |
129 | @Override
130 | public void onUnbind(boolean success, String userId) {
131 |
132 | }
133 | }
134 | }
--------------------------------------------------------------------------------