mirror of
https://github.com/WuKongIM/WuKongIMAndroidSDK
synced 2025-06-03 23:58:19 +00:00
Compatible stream messages
This commit is contained in:
parent
fc1958cf13
commit
d4be779c72
Binary file not shown.
@ -1 +1 @@
|
||||
72f35014c22dcbfefb5ead739964975c
|
||||
4cec5fa9bfdf46b27bf0f92d5fc1e0c0
|
@ -1 +1 @@
|
||||
eb25fc6ecec221cfb5f46d6804366ed0a49417f0
|
||||
8871f573ae5c19bbc5aa201471550587db204a50
|
@ -1 +1 @@
|
||||
21dabdaa369dad1fe075c88136c9520f1009b7d7867b4abdc5471ccf9571059d
|
||||
b91dd2bb576fa13822fcfb913eb376a75a4c44fb3532bcc32f6ef55dacf1df7d
|
@ -1 +1 @@
|
||||
5dcb35c9ef5e3380f55956f83da6bf5c92a3da3edaf69be371466510578a77f29e0efe377fe11c3c5472188b067b2e83683747a3b4408a9fc953eaa1b7cee2be
|
||||
cdfb6e0fe8c3d76a5da917346f2cf502b6958238fb136dc3badc9b26d9612b249477a2cabac267265dc07cd425b80103c8acf57baaebfd03aa80215c9a67e049
|
Binary file not shown.
@ -0,0 +1 @@
|
||||
a811ccc79ea28ce25f32df13d58450d0
|
@ -0,0 +1 @@
|
||||
84a98cd67120c6bf427fe06bf1122bf9ad9eb343
|
@ -0,0 +1 @@
|
||||
a02b43e21138332b7eb0213a91a1411ee6235ff29ae89cc4d33978a7ef08d4be
|
@ -0,0 +1 @@
|
||||
0e160dd8c66ec6f486f66151ae954b2fbdf5b198a9ed969cc4dd48c575db03b23ff8e65ff3fd2c950042fe749d5c68aef27348f70884fcf485cbb5a33bc392ba
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.xinbida.wukongim</groupId>
|
||||
<artifactId>WKIMLib_loca</artifactId>
|
||||
<version>1.0.7</version>
|
||||
<packaging>aar</packaging>
|
||||
</project>
|
@ -0,0 +1 @@
|
||||
6498b4614db03e1905bf001469cf95fa
|
@ -0,0 +1 @@
|
||||
ce43a2b1beb2ca1154356fa7a58990513fbfcaf5
|
@ -0,0 +1 @@
|
||||
2256a0f7a1909d270406d96d1bbee652f83f215d3594de4de1e4fc3153f1ba43
|
@ -0,0 +1 @@
|
||||
e0ba06d4ca0412ea3db840f193369a48db5fbc60eb0745042a35e96e3ccb8dad3acc3f09bec4dbcef7cee13806ea68d431ac28aceaa316f5168177039accf7b3
|
@ -3,11 +3,12 @@
|
||||
<groupId>com.xinbida.wukongim</groupId>
|
||||
<artifactId>WKIMLib_loca</artifactId>
|
||||
<versioning>
|
||||
<latest>1.0.1</latest>
|
||||
<release>1.0.1</release>
|
||||
<latest>1.0.7</latest>
|
||||
<release>1.0.7</release>
|
||||
<versions>
|
||||
<version>1.0.1</version>
|
||||
<version>1.0.7</version>
|
||||
</versions>
|
||||
<lastUpdated>20230823022239</lastUpdated>
|
||||
<lastUpdated>20230829073008</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
||||
|
@ -1 +1 @@
|
||||
78bcfc18b1a294860edba2e4b488ed1e
|
||||
b49f24f693949485c42489310069855c
|
@ -1 +1 @@
|
||||
e066d8085f791ea404c493fe8683c96f788643bf
|
||||
afdc20fb84ea50e9266c2fc71e828a54e4986b03
|
@ -1 +1 @@
|
||||
c35b0d1ac9132a9bca006c5263fa4bb120d0f36487e1a97c8bed3f57770c19af
|
||||
4154fb5d8b1d9905f6b41ee3f017fbf8546309ee40eedb31b159609390163e61
|
@ -1 +1 @@
|
||||
d798765fbd3a123f0cb55e233624263f43abe5f8a3dce892e6dd0a26d15967c2a2533d597fa407b72e4f1dc553b58af5bd0785de63f4d56c297b200ced63f5c5
|
||||
4c8e8bbaa6e68ee2a84da4bf15f5d4aa76419028283f37890c1fa98690d53365746d86c7aa54c76cb6a8c30e60707e6c2a236628bfe7cc887af8262e18da2fa8
|
@ -11,7 +11,7 @@ afterEvaluate {
|
||||
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
|
||||
groupId = 'com.xinbida.wukongim'
|
||||
artifactId = 'WKIMLib_loca'
|
||||
version = '1.0.1'
|
||||
version = '1.0.7'
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
|
3
wkim/proguard-rules.pro
vendored
3
wkim/proguard-rules.pro
vendored
@ -25,10 +25,7 @@
|
||||
-keep class org.xsocket.** { *; }
|
||||
-keep class javax.ws.rs.** { *; }
|
||||
-keep class com.xinbida.wukongim.WKIM {*;}
|
||||
-keep class com.xinbida.wukongim.protocol.WKMessageContent {*;}
|
||||
-keep class com.xinbida.wukongim.protocol.WKMsgEntity {*;}
|
||||
-keep class com.xinbida.wukongim.message.type.WKMsgContentType { *; }
|
||||
-keep class com.xinbida.wukongim.entity.WKChannelType { *; }
|
||||
-keep class com.xinbida.wukongim.message.type.WKSendMsgResult { *; }
|
||||
-keep class com.xinbida.wukongim.message.type.WKConnectStatus { *; }
|
||||
-keep class com.xinbida.wukongim.message.type.WKConnectReason { *; }
|
||||
|
@ -19,7 +19,7 @@ import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
* 5/20/21 5:25 PM
|
||||
*/
|
||||
public class WKIM {
|
||||
private final String Version = "V1.0.0";
|
||||
private final String Version = "V1.0.7";
|
||||
|
||||
private WKIM() {
|
||||
|
||||
|
@ -22,7 +22,7 @@ import com.xinbida.wukongim.entity.WKMsgSetting;
|
||||
import com.xinbida.wukongim.interfaces.IGetOrSyncHistoryMsgBack;
|
||||
import com.xinbida.wukongim.manager.MsgManager;
|
||||
import com.xinbida.wukongim.message.type.WKSendMsgResult;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKMessageContent;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
@ -7,7 +7,7 @@ import com.xinbida.wukongim.WKIM;
|
||||
import com.xinbida.wukongim.manager.ChannelManager;
|
||||
import com.xinbida.wukongim.manager.ChannelMembersManager;
|
||||
import com.xinbida.wukongim.message.type.WKSendMsgResult;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKMessageContent;
|
||||
import com.xinbida.wukongim.utils.DateUtils;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
@ -3,7 +3,7 @@ package com.xinbida.wukongim.entity;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKMessageContent;
|
||||
|
||||
public class WKMsgExtra implements Parcelable {
|
||||
public String messageID;
|
||||
|
@ -8,6 +8,8 @@ public class WKMsgSetting implements Parcelable {
|
||||
public int receipt;
|
||||
// 是否开启top
|
||||
public int topic;
|
||||
// 是否未流消息
|
||||
public int stream;
|
||||
|
||||
public WKMsgSetting() {
|
||||
}
|
||||
@ -15,6 +17,7 @@ public class WKMsgSetting implements Parcelable {
|
||||
protected WKMsgSetting(Parcel in) {
|
||||
receipt = in.readInt();
|
||||
topic = in.readInt();
|
||||
stream = in.readInt();
|
||||
}
|
||||
|
||||
public static final Creator<WKMsgSetting> CREATOR = new Creator<WKMsgSetting>() {
|
||||
@ -38,5 +41,6 @@ public class WKMsgSetting implements Parcelable {
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(receipt);
|
||||
dest.writeInt(topic);
|
||||
dest.writeInt(stream);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
package com.xinbida.wukongim.entity;
|
||||
|
||||
public class WKSignalKey {
|
||||
public String UID;
|
||||
public int registrationID;
|
||||
public String identityKey;
|
||||
public int signedPreKeyID;
|
||||
public String signedPubKey;
|
||||
public String signedSignature;
|
||||
public WKOneTimePreKey oneTimePreKey;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.xinbida.wukongim.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WKSignalProtocolData {
|
||||
public byte channelType;
|
||||
public String channelID;
|
||||
public String identityKey;
|
||||
public int signedPreKeyID;
|
||||
public String signedPubKey;
|
||||
public String signedSignature;
|
||||
public int registrationID;
|
||||
public List<WKOneTimePreKey> oneTimePreKeyList;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.xinbida.wukongim.entity;
|
||||
|
||||
/**
|
||||
* 2020-10-09 15:12
|
||||
* 最近消息
|
||||
*/
|
||||
public class WKSyncRecentHeader {
|
||||
public int no_persist;
|
||||
public int red_dot;
|
||||
public int sync_once;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.xinbida.wukongim.interfaces;
|
||||
|
||||
public interface ICryptoSignalData {
|
||||
void getChannelSignalData(String channelID, byte channelTyp, ICryptoSignalDataResult iCryptoSignalDataResult);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.xinbida.wukongim.interfaces;
|
||||
|
||||
import com.xinbida.wukongim.entity.WKSignalKey;
|
||||
|
||||
public interface ICryptoSignalDataResult {
|
||||
void onResult(WKSignalKey signalKey);
|
||||
}
|
@ -21,7 +21,7 @@ public interface IReceivedMsgListener {
|
||||
/**
|
||||
* 心跳消息
|
||||
*/
|
||||
void heartbeatMsg(WKPongMsg msgHeartbeat);
|
||||
void pongMsg(WKPongMsg pongMsg);
|
||||
|
||||
/**
|
||||
* 被踢消息
|
||||
@ -35,13 +35,6 @@ public interface IReceivedMsgListener {
|
||||
*/
|
||||
void sendAckMsg(WKSendAckMsg sendAckMsg);
|
||||
|
||||
/**
|
||||
* 聊天消息
|
||||
*
|
||||
* @param msg 消息对象
|
||||
*/
|
||||
void receiveMsg(WKMsg msg);
|
||||
|
||||
/**
|
||||
* 重连
|
||||
*/
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.xinbida.wukongim.interfaces;
|
||||
|
||||
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKMessageContent;
|
||||
|
||||
/**
|
||||
* 2019-11-10 16:12
|
||||
|
@ -6,7 +6,7 @@ import com.xinbida.wukongim.WKIM;
|
||||
import com.xinbida.wukongim.WKIMApplication;
|
||||
import com.xinbida.wukongim.interfaces.IConnectionStatus;
|
||||
import com.xinbida.wukongim.interfaces.IGetIpAndPort;
|
||||
import com.xinbida.wukongim.message.ConnectionHandler;
|
||||
import com.xinbida.wukongim.message.WKConnection;
|
||||
import com.xinbida.wukongim.message.MessageHandler;
|
||||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
|
||||
@ -37,11 +37,12 @@ public class ConnectionManager extends BaseManager {
|
||||
// 连接
|
||||
public void connection() {
|
||||
if (TextUtils.isEmpty(WKIMApplication.getInstance().getToken()) || TextUtils.isEmpty(WKIMApplication.getInstance().getUid())) {
|
||||
throw new NullPointerException("连接UID和Token不能为空");
|
||||
WKLoggerUtils.getInstance().d("未初始化uid和token");
|
||||
return;
|
||||
}
|
||||
WKIMApplication.getInstance().isCanConnect = true;
|
||||
if (ConnectionHandler.getInstance().connectionIsNull()) {
|
||||
ConnectionHandler.getInstance().reconnection();
|
||||
if (WKConnection.getInstance().connectionIsNull()) {
|
||||
WKConnection.getInstance().reconnection();
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +62,7 @@ public class ConnectionManager extends BaseManager {
|
||||
*/
|
||||
private void stopConnect() {
|
||||
WKIMApplication.getInstance().isCanConnect = false;
|
||||
ConnectionHandler.getInstance().stopAll();
|
||||
WKConnection.getInstance().stopAll();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,7 +75,7 @@ public class ConnectionManager extends BaseManager {
|
||||
|
||||
WKIMApplication.getInstance().setToken("");
|
||||
MessageHandler.getInstance().updateLastSendingMsgFail();
|
||||
ConnectionHandler.getInstance().stopAll();
|
||||
WKConnection.getInstance().stopAll();
|
||||
WKIM.getInstance().getChannelManager().clearARMCache();
|
||||
WKIMApplication.getInstance().closeDbHelper();
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ import com.xinbida.wukongim.interfaces.ISyncOfflineMsgListener;
|
||||
import com.xinbida.wukongim.interfaces.IUploadAttacResultListener;
|
||||
import com.xinbida.wukongim.interfaces.IUploadAttachmentListener;
|
||||
import com.xinbida.wukongim.interfaces.IUploadMsgExtraListener;
|
||||
import com.xinbida.wukongim.message.ConnectionHandler;
|
||||
import com.xinbida.wukongim.message.WKConnection;
|
||||
import com.xinbida.wukongim.message.MessageHandler;
|
||||
import com.xinbida.wukongim.message.type.WKMsgContentType;
|
||||
import com.xinbida.wukongim.message.type.WKSendMsgResult;
|
||||
@ -47,8 +47,8 @@ import com.xinbida.wukongim.msgmodel.WKReply;
|
||||
import com.xinbida.wukongim.msgmodel.WKTextContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKVideoContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKVoiceContent;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
import com.xinbida.wukongim.protocol.WKMsgEntity;
|
||||
import com.xinbida.wukongim.msgmodel.WKMessageContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKMsgEntity;
|
||||
import com.xinbida.wukongim.utils.DateUtils;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
@ -1193,11 +1193,11 @@ public class MsgManager extends BaseManager {
|
||||
|
||||
|
||||
public void sendMessage(WKMessageContent messageContent, String channelID, byte channelType) {
|
||||
ConnectionHandler.getInstance().sendMessage(messageContent, channelID, channelType);
|
||||
WKConnection.getInstance().sendMessage(messageContent, channelID, channelType);
|
||||
}
|
||||
|
||||
public void sendMessage(WKMessageContent messageContent, WKMsgSetting setting, String channelID, byte channelType) {
|
||||
ConnectionHandler.getInstance().sendMessage(messageContent, setting, channelID, channelType);
|
||||
WKConnection.getInstance().sendMessage(messageContent, setting, channelID, channelType);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1206,7 +1206,7 @@ public class MsgManager extends BaseManager {
|
||||
* @param msg 消息对象
|
||||
*/
|
||||
public void sendMessage(WKMsg msg) {
|
||||
ConnectionHandler.getInstance().sendMessage(msg);
|
||||
WKConnection.getInstance().sendMessage(msg);
|
||||
}
|
||||
|
||||
public String createClientMsgNO() {
|
||||
|
@ -21,43 +21,43 @@ import java.nio.BufferUnderflowException;
|
||||
* 2020-12-18 10:28
|
||||
* 连接客户端
|
||||
*/
|
||||
class ClientHandler implements IDataHandler, IConnectHandler,
|
||||
class ConnectionClient implements IDataHandler, IConnectHandler,
|
||||
IDisconnectHandler, IConnectExceptionHandler,
|
||||
IConnectionTimeoutHandler, IIdleTimeoutHandler {
|
||||
|
||||
private boolean isConnectSuccess;
|
||||
|
||||
ClientHandler() {
|
||||
ConnectionClient() {
|
||||
isConnectSuccess = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onConnectException(INonBlockingConnection iNonBlockingConnection, IOException e) {
|
||||
WKLoggerUtils.getInstance().e("连接异常");
|
||||
ConnectionHandler.getInstance().forcedReconnection();
|
||||
WKConnection.getInstance().forcedReconnection();
|
||||
close(iNonBlockingConnection);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onConnect(INonBlockingConnection iNonBlockingConnection) throws BufferUnderflowException {
|
||||
if (ConnectionHandler.getInstance().connection == null) {
|
||||
if (WKConnection.getInstance().connection == null) {
|
||||
Log.e("连接信息为空", "--->");
|
||||
}
|
||||
if (ConnectionHandler.getInstance().connection != null && iNonBlockingConnection != null) {
|
||||
if (!ConnectionHandler.getInstance().connection.getId().equals(iNonBlockingConnection.getId())) {
|
||||
if (WKConnection.getInstance().connection != null && iNonBlockingConnection != null) {
|
||||
if (!WKConnection.getInstance().connection.getId().equals(iNonBlockingConnection.getId())) {
|
||||
close(iNonBlockingConnection);
|
||||
ConnectionHandler.getInstance().forcedReconnection();
|
||||
WKConnection.getInstance().forcedReconnection();
|
||||
} else {
|
||||
//连接成功
|
||||
isConnectSuccess = true;
|
||||
WKLoggerUtils.getInstance().e("连接成功");
|
||||
ConnectionHandler.getInstance().sendConnectMsg();
|
||||
WKConnection.getInstance().sendConnectMsg();
|
||||
}
|
||||
} else {
|
||||
close(iNonBlockingConnection);
|
||||
WKLoggerUtils.getInstance().e("连接成功连接对象为空");
|
||||
ConnectionHandler.getInstance().forcedReconnection();
|
||||
WKConnection.getInstance().forcedReconnection();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -66,7 +66,7 @@ class ClientHandler implements IDataHandler, IConnectHandler,
|
||||
public boolean onConnectionTimeout(INonBlockingConnection iNonBlockingConnection) {
|
||||
if (!isConnectSuccess) {
|
||||
WKLoggerUtils.getInstance().e("连接超时");
|
||||
ConnectionHandler.getInstance().forcedReconnection();
|
||||
WKConnection.getInstance().forcedReconnection();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -74,25 +74,29 @@ class ClientHandler implements IDataHandler, IConnectHandler,
|
||||
@Override
|
||||
public boolean onData(INonBlockingConnection iNonBlockingConnection) throws BufferUnderflowException {
|
||||
Object id = iNonBlockingConnection.getAttachment();
|
||||
if (id != null) {
|
||||
if (!TextUtils.isEmpty(ConnectionHandler.getInstance().socketSingleID) && !ConnectionHandler.getInstance().socketSingleID.equals(id)) {
|
||||
if (id instanceof String) {
|
||||
if (id.toString().startsWith("close")){
|
||||
return true;
|
||||
}
|
||||
if (!TextUtils.isEmpty(WKConnection.getInstance().socketSingleID) && !WKConnection.getInstance().socketSingleID.equals(id)) {
|
||||
WKLoggerUtils.getInstance().e("收到的消息ID和连接的ID对应不上---");
|
||||
try {
|
||||
iNonBlockingConnection.close();
|
||||
ConnectionHandler.getInstance().connection.close();
|
||||
if (WKConnection.getInstance().connection != null) {
|
||||
WKConnection.getInstance().connection.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
ConnectionHandler.getInstance().forcedReconnection();
|
||||
if (WKIMApplication.getInstance().isCanConnect) {
|
||||
WKConnection.getInstance().forcedReconnection();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int available_len;
|
||||
// byte[] available_bytes = null;
|
||||
int bufLen = 102400;
|
||||
try {
|
||||
|
||||
available_len = iNonBlockingConnection.available();
|
||||
if (available_len == -1) {
|
||||
return true;
|
||||
@ -111,7 +115,7 @@ class ClientHandler implements IDataHandler, IConnectHandler,
|
||||
}
|
||||
byte[] buffBytes = iNonBlockingConnection.readBytesByLength(readLen);
|
||||
if (buffBytes.length > 0) {
|
||||
ConnectionHandler.getInstance().receivedData(buffBytes);
|
||||
WKConnection.getInstance().receivedData(buffBytes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +141,7 @@ class ClientHandler implements IDataHandler, IConnectHandler,
|
||||
}
|
||||
}
|
||||
if (WKIMApplication.getInstance().isCanConnect) {
|
||||
ConnectionHandler.getInstance().forcedReconnection();
|
||||
WKConnection.getInstance().forcedReconnection();
|
||||
} else {
|
||||
WKLoggerUtils.getInstance().e("不能重连-->");
|
||||
}
|
||||
@ -149,7 +153,7 @@ class ClientHandler implements IDataHandler, IConnectHandler,
|
||||
public boolean onIdleTimeout(INonBlockingConnection iNonBlockingConnection) {
|
||||
if (!isConnectSuccess) {
|
||||
WKLoggerUtils.getInstance().e("Idle连接超时");
|
||||
ConnectionHandler.getInstance().forcedReconnection();
|
||||
WKConnection.getInstance().forcedReconnection();
|
||||
close(iNonBlockingConnection);
|
||||
}
|
||||
return true;
|
@ -1,609 +0,0 @@
|
||||
package com.xinbida.wukongim.message;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.xinbida.wukongim.WKIM;
|
||||
import com.xinbida.wukongim.WKIMApplication;
|
||||
import com.xinbida.wukongim.db.MsgDbManager;
|
||||
import com.xinbida.wukongim.db.WKDBColumns;
|
||||
import com.xinbida.wukongim.entity.WKConversationMsgExtra;
|
||||
import com.xinbida.wukongim.entity.WKMsg;
|
||||
import com.xinbida.wukongim.entity.WKMsgSetting;
|
||||
import com.xinbida.wukongim.entity.WKUIConversationMsg;
|
||||
import com.xinbida.wukongim.message.type.WKMsgType;
|
||||
import com.xinbida.wukongim.message.type.WKSendMsgResult;
|
||||
import com.xinbida.wukongim.msgmodel.WKMediaMessageContent;
|
||||
import com.xinbida.wukongim.protocol.WKBaseMsg;
|
||||
import com.xinbida.wukongim.protocol.WKConnectAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKConnectMsg;
|
||||
import com.xinbida.wukongim.protocol.WKDisconnectMsg;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
import com.xinbida.wukongim.protocol.WKMsgEntity;
|
||||
import com.xinbida.wukongim.protocol.WKPingMsg;
|
||||
import com.xinbida.wukongim.protocol.WKPongMsg;
|
||||
import com.xinbida.wukongim.protocol.WKReceivedAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKReceivedMsg;
|
||||
import com.xinbida.wukongim.protocol.WKSendAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKSendMsg;
|
||||
import com.xinbida.wukongim.utils.BigTypeUtils;
|
||||
import com.xinbida.wukongim.utils.CryptoUtils;
|
||||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* 5/21/21 11:28 AM
|
||||
* 收发消息转换
|
||||
*/
|
||||
class MessageConvertHandler {
|
||||
|
||||
private MessageConvertHandler() {
|
||||
}
|
||||
|
||||
private static class MessageConvertHandlerBinder {
|
||||
static final MessageConvertHandler msgConvert = new MessageConvertHandler();
|
||||
}
|
||||
|
||||
public static MessageConvertHandler getInstance() {
|
||||
return MessageConvertHandlerBinder.msgConvert;
|
||||
}
|
||||
|
||||
byte[] enConnectMsg(WKConnectMsg connectMsg) {
|
||||
int remainingLength = connectMsg.getFixedHeaderLength()
|
||||
+ connectMsg.deviceIDLength
|
||||
+ connectMsg.deviceID.length()
|
||||
+ connectMsg.uidLength
|
||||
+ WKIMApplication.getInstance().getUid().length()
|
||||
+ connectMsg.tokenLength
|
||||
+ WKIMApplication.getInstance().getToken().length()
|
||||
+ connectMsg.clientTimeStampLength
|
||||
+ connectMsg.clientKeyLength
|
||||
+ CryptoUtils.getInstance().getPublicKey().length();
|
||||
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(remainingLength);
|
||||
int totalLen = 1 + remainingBytes.length
|
||||
+ connectMsg.protocolVersionLength
|
||||
+ connectMsg.deviceFlagLength
|
||||
+ connectMsg.deviceIDLength
|
||||
+ connectMsg.deviceID.length()
|
||||
+ connectMsg.uidLength
|
||||
+ WKIMApplication.getInstance().getUid().length()
|
||||
+ connectMsg.tokenLength
|
||||
+ WKIMApplication.getInstance().getToken().length()
|
||||
+ connectMsg.clientTimeStampLength
|
||||
+ connectMsg.clientKeyLength
|
||||
+ CryptoUtils.getInstance().getPublicKey().length();
|
||||
|
||||
byte[] bytes = new byte[totalLen];
|
||||
ByteBuffer buffer = ByteBuffer.allocate(totalLen).order(
|
||||
ByteOrder.BIG_ENDIAN);
|
||||
try {
|
||||
//固定头
|
||||
buffer.put(WKTypeUtils.getInstance().getHeader(connectMsg.packetType, connectMsg.flag, 0, 0));
|
||||
buffer.put(remainingBytes);
|
||||
buffer.put(connectMsg.protocolVersion);
|
||||
buffer.put(connectMsg.deviceFlag);
|
||||
buffer.putShort((short) connectMsg.deviceID.length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(connectMsg.deviceID));
|
||||
buffer.putShort((short) WKIMApplication.getInstance().getUid().length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(WKIMApplication.getInstance().getUid()));
|
||||
buffer.putShort((short) WKIMApplication.getInstance().getToken().length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(WKIMApplication.getInstance().getToken()));
|
||||
buffer.putLong(connectMsg.clientTimestamp);
|
||||
buffer.putShort((short) CryptoUtils.getInstance().getPublicKey().length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(CryptoUtils.getInstance().getPublicKey()));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
buffer.position(0);
|
||||
buffer.get(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
synchronized byte[] enReceivedAckMsg(WKReceivedAckMsg receivedAckMsg) {
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(8 + 4);
|
||||
|
||||
int totalLen = 1 + remainingBytes.length + 8 + 4;
|
||||
byte[] bytes = new byte[totalLen];
|
||||
ByteBuffer buffer = ByteBuffer.allocate(totalLen).order(
|
||||
ByteOrder.BIG_ENDIAN);
|
||||
//固定头
|
||||
buffer.put(WKTypeUtils.getInstance().getHeader(receivedAckMsg.packetType, receivedAckMsg.no_persist ? 1 : 0, receivedAckMsg.red_dot ? 1 : 0, receivedAckMsg.sync_once ? 1 : 0));
|
||||
buffer.put(remainingBytes);
|
||||
BigInteger bigInteger = new BigInteger(receivedAckMsg.messageID);
|
||||
buffer.putLong(bigInteger.longValue());
|
||||
buffer.putInt(receivedAckMsg.messageSeq);
|
||||
buffer.position(0);
|
||||
buffer.get(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
byte[] enPingMsg(WKPingMsg pingMsg) {
|
||||
int totalLen = 1;
|
||||
byte[] bytes = new byte[totalLen];
|
||||
ByteBuffer buffer = ByteBuffer.allocate(totalLen).order(
|
||||
ByteOrder.BIG_ENDIAN);
|
||||
//固定头
|
||||
buffer.put(WKTypeUtils.getInstance().getHeader(pingMsg.packetType, pingMsg.flag, 0, 0));
|
||||
buffer.position(0);
|
||||
buffer.get(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
byte[] enSendMsg(WKSendMsg sendMsg) {
|
||||
// 先加密内容
|
||||
byte[] contentByte = CryptoUtils.getInstance().aesEncrypt(sendMsg.payload);
|
||||
String sendContent = CryptoUtils.getInstance().base64Encode(contentByte);
|
||||
String msgKey = sendMsg.clientSeq
|
||||
+ sendMsg.clientMsgNo
|
||||
+ sendMsg.channelId
|
||||
+ sendMsg.channelType
|
||||
+ sendContent;
|
||||
byte[] msgKeyByte = CryptoUtils.getInstance().aesEncrypt(msgKey);
|
||||
String msgKeyContent = CryptoUtils.getInstance().base64Encode(msgKeyByte);
|
||||
msgKeyContent = CryptoUtils.getInstance().digestMD5(msgKeyContent);
|
||||
|
||||
int topicLen = 0;
|
||||
if (sendMsg.setting.topic == 1) {
|
||||
topicLen = sendMsg.topicID.length();
|
||||
topicLen += sendMsg.topicIDLength;
|
||||
}
|
||||
int remainingLength = sendMsg.settingLength
|
||||
+ sendMsg.clientSeqLength
|
||||
+ sendMsg.clientMsgNoLength + sendMsg.clientMsgNo.length()
|
||||
+ sendMsg.channelIdLength + sendMsg.channelId.length()
|
||||
+ sendMsg.channelTypeLength
|
||||
+ sendMsg.msgKeyLength + msgKeyContent.length()
|
||||
+ topicLen
|
||||
+ sendContent.getBytes().length;
|
||||
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(remainingLength);
|
||||
|
||||
int totalLen = 1 + remainingBytes.length
|
||||
+ sendMsg.settingLength
|
||||
+ sendMsg.clientSeqLength
|
||||
+ sendMsg.clientMsgNoLength
|
||||
+ sendMsg.clientMsgNo.length()
|
||||
+ sendMsg.channelIdLength
|
||||
+ sendMsg.channelId.length()
|
||||
+ sendMsg.channelTypeLength
|
||||
+ sendMsg.msgKeyLength
|
||||
+ msgKeyContent.length()
|
||||
+ topicLen
|
||||
+ sendContent.getBytes().length;
|
||||
|
||||
byte[] bytes = new byte[totalLen];
|
||||
ByteBuffer buffer = ByteBuffer.allocate(totalLen).order(
|
||||
ByteOrder.BIG_ENDIAN);
|
||||
try {
|
||||
//固定头
|
||||
buffer.put(WKTypeUtils.getInstance().getHeader(sendMsg.packetType, sendMsg.no_persist ? 1 : 0, sendMsg.red_dot ? 1 : 0, sendMsg.sync_once ? 1 : 0));
|
||||
buffer.put(remainingBytes);
|
||||
//消息设置
|
||||
buffer.put(WKTypeUtils.getInstance().getMsgSetting(sendMsg.setting));
|
||||
|
||||
buffer.putInt(sendMsg.clientSeq);
|
||||
buffer.putShort((short) sendMsg.clientMsgNo.length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(sendMsg.clientMsgNo));
|
||||
buffer.putShort((short) sendMsg.channelId.length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(sendMsg.channelId));
|
||||
buffer.put(sendMsg.channelType);
|
||||
buffer.putShort((short) msgKeyContent.length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(msgKeyContent));
|
||||
// 添加话题
|
||||
if (sendMsg.setting.topic == 1) {
|
||||
buffer.putShort((short) sendMsg.topicID.length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(sendMsg.topicID));
|
||||
}
|
||||
byte[] contentBytes = WKTypeUtils.getInstance().stringToByte(sendContent);
|
||||
buffer.put(contentBytes);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
buffer.position(0);
|
||||
buffer.get(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
WKBaseMsg decodeMessage(byte[] bytes) {
|
||||
//包类型
|
||||
InputStream inputStream = new ByteArrayInputStream(bytes);
|
||||
byte[] fixedHeader = new byte[1];
|
||||
try {
|
||||
int headerRead = inputStream.read(fixedHeader);
|
||||
if (headerRead == -1) return null;
|
||||
int packetType = WKTypeUtils.getInstance().getHeight4(fixedHeader[0]);
|
||||
int remainingLength = WKTypeUtils.getInstance().bytes2Length(inputStream);
|
||||
if (packetType == WKMsgType.CONNACK) {
|
||||
// 连接ack
|
||||
WKConnectAckMsg connectAckMsg = new WKConnectAckMsg();
|
||||
int read;
|
||||
|
||||
// 客户端时间与服务器的差值,单位毫秒
|
||||
byte[] length_byte = new byte[8];
|
||||
read = inputStream.read(length_byte);
|
||||
if (read == -1) {
|
||||
return connectAckMsg;
|
||||
}
|
||||
long time = BigTypeUtils.getInstance().bytesToLong(length_byte);
|
||||
|
||||
// 连接原因码
|
||||
byte[] reasonByte = new byte[1];
|
||||
read = inputStream.read(reasonByte);
|
||||
if (read == -1) {
|
||||
return connectAckMsg;
|
||||
}
|
||||
|
||||
// 获取公钥长度
|
||||
byte[] serverKeyLengthByte = new byte[2];
|
||||
read = inputStream.read(serverKeyLengthByte);
|
||||
if (read == -1) return connectAckMsg;
|
||||
short serverKeyLength = BigTypeUtils.getInstance().byteToShort(serverKeyLengthByte);
|
||||
// 服务端公钥
|
||||
byte[] serverKeyByte = new byte[serverKeyLength];
|
||||
read = inputStream.read(serverKeyByte);
|
||||
if (read == -1) return connectAckMsg;
|
||||
String serverKey = WKTypeUtils.getInstance().bytesToString(serverKeyByte);
|
||||
// 获取安全码AES加密需要
|
||||
byte[] saltLengthByte = new byte[2];
|
||||
read = inputStream.read(saltLengthByte);
|
||||
if (read == -1) return connectAckMsg;
|
||||
short saltLength = BigTypeUtils.getInstance().byteToShort(saltLengthByte);
|
||||
// 安全码
|
||||
byte[] saltByte = new byte[saltLength];
|
||||
read = inputStream.read(saltByte);
|
||||
if (read == -1) return connectAckMsg;
|
||||
String salt = WKTypeUtils.getInstance().bytesToString(saltByte);
|
||||
connectAckMsg.serverKey = serverKey;
|
||||
connectAckMsg.salt = salt;
|
||||
//保存公钥和安全码
|
||||
CryptoUtils.getInstance().setServerKeyAndSalt(connectAckMsg.serverKey, connectAckMsg.salt);
|
||||
|
||||
connectAckMsg.timeDiff = time;
|
||||
connectAckMsg.remainingLength = remainingLength;
|
||||
connectAckMsg.reasonCode = reasonByte[0];
|
||||
return connectAckMsg;
|
||||
} else if (packetType == WKMsgType.SENDACK) {
|
||||
WKSendAckMsg sendAckMsg = new WKSendAckMsg();
|
||||
// 发送消息ack
|
||||
byte[] messageId = new byte[8];
|
||||
int read = inputStream.read(messageId);
|
||||
if (read == -1) return sendAckMsg;
|
||||
BigInteger bigInteger = new BigInteger(messageId);
|
||||
if (bigInteger.toString().startsWith("-")) {
|
||||
BigInteger temp = new BigInteger("18446744073709551616");
|
||||
sendAckMsg.messageID = temp.add(bigInteger).toString();
|
||||
} else
|
||||
sendAckMsg.messageID = bigInteger.toString();
|
||||
//sendAckMsg.messageID = BigTypeUtils.getInstance().bytesToLong(messageId) + "";
|
||||
WKLoggerUtils.getInstance().e("发送ack msgid:" + sendAckMsg.messageID);
|
||||
// 客户端序列号
|
||||
byte[] clientSeq = new byte[4];
|
||||
read = inputStream.read(clientSeq);
|
||||
if (read == -1) return sendAckMsg;
|
||||
sendAckMsg.clientSeq = BigTypeUtils.getInstance().bytesToInt(clientSeq);
|
||||
|
||||
// 服务器序号
|
||||
byte[] messageSqe = new byte[4];
|
||||
read = inputStream.read(messageSqe);
|
||||
if (read == -1) return sendAckMsg;
|
||||
sendAckMsg.messageSeq = BigTypeUtils.getInstance().bytesToInt(messageSqe);
|
||||
|
||||
// 失败原因
|
||||
byte[] reasonCode = new byte[1];
|
||||
read = inputStream.read(reasonCode);
|
||||
if (read == -1) return sendAckMsg;
|
||||
sendAckMsg.reasonCode = reasonCode[0];
|
||||
WKLoggerUtils.getInstance().e("发送返回原因:"+sendAckMsg.reasonCode);
|
||||
return sendAckMsg;
|
||||
} else if (packetType == WKMsgType.DISCONNECT) {
|
||||
WKDisconnectMsg disconnectMsg = new WKDisconnectMsg();
|
||||
byte[] reasonCode = new byte[1];
|
||||
int read = inputStream.read(reasonCode);
|
||||
if (read == -1) return disconnectMsg;
|
||||
disconnectMsg.reasonCode = reasonCode[0];
|
||||
byte[] reasonByte = new byte[remainingLength - 1];
|
||||
if (reasonByte.length != 0) {
|
||||
read = inputStream.read(reasonByte);
|
||||
if (read == -1) return disconnectMsg;
|
||||
disconnectMsg.reason = WKTypeUtils.getInstance().bytesToString(reasonByte);
|
||||
}
|
||||
WKLoggerUtils.getInstance().e("sdk收到被踢的消息--->");
|
||||
WKLoggerUtils.getInstance().e("被踢的原因:" + disconnectMsg.reason);
|
||||
return disconnectMsg;
|
||||
} else if (packetType == WKMsgType.RECVEIVED) {
|
||||
//接受消息
|
||||
WKReceivedMsg receivedMsg = new WKReceivedMsg();
|
||||
int read;
|
||||
//消息设置
|
||||
byte[] setting = new byte[1];
|
||||
read = inputStream.read(setting);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.setting = WKTypeUtils.getInstance().getMsgSetting(setting[0]);
|
||||
|
||||
// 消息Key
|
||||
byte[] msgKeyLengthByte = new byte[2];
|
||||
read = inputStream.read(msgKeyLengthByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
short msgKeyLength = BigTypeUtils.getInstance().byteToShort(msgKeyLengthByte);
|
||||
byte[] msgKeyByte = new byte[msgKeyLength];
|
||||
read = inputStream.read(msgKeyByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.msgKey = WKTypeUtils.getInstance().bytesToString(msgKeyByte);
|
||||
|
||||
// 发送者ID
|
||||
byte[] fromUIDLengthByte = new byte[2];
|
||||
read = inputStream.read(fromUIDLengthByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
short fromUIDLength = BigTypeUtils.getInstance().byteToShort(fromUIDLengthByte);
|
||||
byte[] fromUIDByte = new byte[fromUIDLength];
|
||||
read = inputStream.read(fromUIDByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.fromUID = WKTypeUtils.getInstance().bytesToString(fromUIDByte);
|
||||
|
||||
// 频道id长度
|
||||
byte[] channelIdLengthByte = new byte[2];
|
||||
read = inputStream.read(channelIdLengthByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
// 频道id
|
||||
short channelIdLength = BigTypeUtils.getInstance().byteToShort(channelIdLengthByte);
|
||||
byte[] channelIDByte = new byte[channelIdLength];
|
||||
read = inputStream.read(channelIDByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.channelID = WKTypeUtils.getInstance().bytesToString(channelIDByte);
|
||||
|
||||
// 频道类型
|
||||
byte[] channelType = new byte[1];
|
||||
read = inputStream.read(channelType);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.channelType = channelType[0];
|
||||
|
||||
//解析客户端ID
|
||||
byte[] clientMsgNoLengthByte = new byte[2];
|
||||
read = inputStream.read(clientMsgNoLengthByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
short clientMsgNoLength = BigTypeUtils.getInstance().byteToShort(clientMsgNoLengthByte);
|
||||
// 客户端编号
|
||||
byte[] clientMsgNoByte = new byte[clientMsgNoLength];
|
||||
read = inputStream.read(clientMsgNoByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.clientMsgNo = WKTypeUtils.getInstance().bytesToString(clientMsgNoByte);
|
||||
|
||||
// 消息ID
|
||||
byte[] messageId = new byte[8];
|
||||
read = inputStream.read(messageId);
|
||||
if (read == -1) return receivedMsg;
|
||||
BigInteger bigInteger = new BigInteger(messageId);
|
||||
if (bigInteger.toString().startsWith("-")) {
|
||||
BigInteger temp = new BigInteger("18446744073709551616");
|
||||
receivedMsg.messageID = temp.add(bigInteger).toString();
|
||||
} else
|
||||
receivedMsg.messageID = bigInteger.toString();
|
||||
//receivedMsg.messageID = BigTypeUtils.getInstance().bytesToLong(messageId)+ "";
|
||||
|
||||
//消息序列号
|
||||
byte[] messageSqe = new byte[4];
|
||||
read = inputStream.read(messageSqe);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.messageSeq = BigTypeUtils.getInstance().bytesToInt(messageSqe);
|
||||
|
||||
//消息时间
|
||||
byte[] messageTime = new byte[4];
|
||||
read = inputStream.read(messageTime);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.messageTimestamp = BigTypeUtils.getInstance().bytesToInt(messageTime);
|
||||
|
||||
|
||||
// 话题ID
|
||||
short topicLength = 0;
|
||||
if (receivedMsg.setting.topic == 1) {
|
||||
byte[] topicLengthByte = new byte[2];
|
||||
read = inputStream.read(topicLengthByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
topicLength = BigTypeUtils.getInstance().byteToShort(topicLengthByte);
|
||||
byte[] topicByte = new byte[topicLength];
|
||||
read = inputStream.read(topicByte);
|
||||
if (read == -1) return receivedMsg;
|
||||
receivedMsg.topicID = WKTypeUtils.getInstance().bytesToString(topicByte);
|
||||
// 默认加上字符串标示长度2
|
||||
topicLength += 2;
|
||||
}
|
||||
|
||||
// 消息内容
|
||||
// 消息ID长度8 + 消息序列号长度4 + 消息时间长度4 + setting1 + (客户端ID长度+字符串标示长度2) (频道ID长度+字符串标示长度2) + 频道类型长度1 +(话题长度+字符串标示长度2) +(发送者uid长度+字符串标示长度2)
|
||||
byte[] payload = new byte[remainingLength - (8 + 4 + 2 + 1 + msgKeyLength + 4 + (clientMsgNoLength + 2) + (channelIdLength + 2) + 1 + topicLength + (2 + fromUIDLength))];
|
||||
read = inputStream.read(payload);
|
||||
if (read == -1) return receivedMsg;
|
||||
|
||||
String content = WKTypeUtils.getInstance().bytesToString(payload);
|
||||
receivedMsg.payload = CryptoUtils.getInstance().aesDecrypt(CryptoUtils.getInstance().base64Decode(content));
|
||||
String msgKey = receivedMsg.messageID
|
||||
+ receivedMsg.messageSeq
|
||||
+ receivedMsg.clientMsgNo
|
||||
+ receivedMsg.messageTimestamp
|
||||
+ receivedMsg.fromUID
|
||||
+ receivedMsg.channelID
|
||||
+ receivedMsg.channelType
|
||||
+ content;
|
||||
byte[] result = CryptoUtils.getInstance().aesEncrypt(msgKey);
|
||||
String base64Result = CryptoUtils.getInstance().base64Encode(result);
|
||||
String localMsgKey = CryptoUtils.getInstance().digestMD5(base64Result);
|
||||
if (!localMsgKey.equals(receivedMsg.msgKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
WKLoggerUtils.getInstance().e("接受到消息:" + receivedMsg.payload);
|
||||
return receivedMsg;
|
||||
} else if (packetType == WKMsgType.PONG) {
|
||||
WKLoggerUtils.getInstance().e("Pong消息--->");
|
||||
return new WKPongMsg();
|
||||
} else {
|
||||
WKLoggerUtils.getInstance().e("解析协议类型失败--->:" + packetType);
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
WKLoggerUtils.getInstance().e("解析数据异常------>:" + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发送的消息
|
||||
*
|
||||
* @param msg 本地消息
|
||||
* @return 网络消息
|
||||
*/
|
||||
WKBaseMsg getSendBaseMsg(WKMsg msg) {
|
||||
//发送消息
|
||||
JSONObject jsonObject = null;
|
||||
if (msg.baseContentMsgModel != null) {
|
||||
jsonObject = msg.baseContentMsgModel.encodeMsg();
|
||||
} else {
|
||||
msg.baseContentMsgModel = new WKMessageContent();
|
||||
}
|
||||
try {
|
||||
if (jsonObject == null) jsonObject = new JSONObject();
|
||||
if (!jsonObject.has(WKDBColumns.WKMessageColumns.from_uid)) {
|
||||
jsonObject.put(WKDBColumns.WKMessageColumns.from_uid, WKIMApplication.getInstance().getUid());
|
||||
}
|
||||
jsonObject.put(WKDBColumns.WKMessageColumns.type, msg.type);
|
||||
//判断@情况
|
||||
if (msg.baseContentMsgModel.mentionInfo != null
|
||||
&& msg.baseContentMsgModel.mentionInfo.uids != null
|
||||
&& msg.baseContentMsgModel.mentionInfo.uids.size() > 0) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (int i = 0, size = msg.baseContentMsgModel.mentionInfo.uids.size(); i < size; i++) {
|
||||
jsonArray.put(msg.baseContentMsgModel.mentionInfo.uids.get(i));
|
||||
}
|
||||
if (!jsonObject.has("mention")) {
|
||||
JSONObject mentionJson = new JSONObject();
|
||||
mentionJson.put("all", msg.baseContentMsgModel.mentionAll);
|
||||
mentionJson.put("uids", jsonArray);
|
||||
jsonObject.put("mention", mentionJson);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (msg.baseContentMsgModel.mentionAll == 1) {
|
||||
JSONObject mentionJson = new JSONObject();
|
||||
mentionJson.put("all", msg.baseContentMsgModel.mentionAll);
|
||||
jsonObject.put("mention", mentionJson);
|
||||
}
|
||||
}
|
||||
// 被回复消息
|
||||
if (msg.baseContentMsgModel.reply != null) {
|
||||
jsonObject.put("reply", msg.baseContentMsgModel.reply.encodeMsg());
|
||||
}
|
||||
// 机器人ID
|
||||
if (!TextUtils.isEmpty(msg.baseContentMsgModel.robotID)) {
|
||||
jsonObject.put("robot_id", msg.baseContentMsgModel.robotID);
|
||||
}
|
||||
if (msg.baseContentMsgModel.entities != null && msg.baseContentMsgModel.entities.size() > 0) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (WKMsgEntity entity : msg.baseContentMsgModel.entities) {
|
||||
JSONObject jo = new JSONObject();
|
||||
jo.put("offset", entity.offset);
|
||||
jo.put("length", entity.length);
|
||||
jo.put("type", entity.type);
|
||||
jo.put("value", entity.value);
|
||||
jsonArray.put(jo);
|
||||
}
|
||||
jsonObject.put("entities", jsonArray);
|
||||
}
|
||||
if (msg.baseContentMsgModel.flame != 0) {
|
||||
jsonObject.put("flame_second", msg.baseContentMsgModel.flameSecond);
|
||||
jsonObject.put("flame", msg.baseContentMsgModel.flame);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
WKSendMsg sendMsg = new WKSendMsg();
|
||||
// 默认先设置clientSeq,因为有可能本条消息并不需要入库,UI上自己设置了clientSeq
|
||||
sendMsg.clientSeq = (int) msg.clientSeq;
|
||||
sendMsg.sync_once = msg.header.syncOnce;
|
||||
sendMsg.no_persist = msg.header.noPersist;
|
||||
sendMsg.red_dot = msg.header.redDot;
|
||||
sendMsg.clientMsgNo = msg.clientMsgNO;
|
||||
sendMsg.channelId = msg.channelID;
|
||||
sendMsg.channelType = msg.channelType;
|
||||
sendMsg.topicID = msg.topicID;
|
||||
if (msg.setting == null) msg.setting = new WKMsgSetting();
|
||||
sendMsg.setting = msg.setting;
|
||||
msg.content = jsonObject.toString();
|
||||
long tempOrderSeq = MsgDbManager.getInstance().queryMaxOrderSeqWithChannel(msg.channelID, msg.channelType);
|
||||
msg.orderSeq = tempOrderSeq + 1;
|
||||
// 需要存储的消息入库后更改消息的clientSeq
|
||||
if (!sendMsg.no_persist) {
|
||||
sendMsg.clientSeq = (int) (msg.clientSeq = (int) MsgDbManager.getInstance().insert(msg));
|
||||
if (msg.clientSeq > 0) {
|
||||
// TODO: 2022/4/27
|
||||
WKUIConversationMsg uiMsg = WKIM.getInstance().getConversationManager().updateWithWKMsg(msg);
|
||||
if (uiMsg != null) {
|
||||
long browseTo = WKIM.getInstance().getMsgManager().getMaxMessageSeqWithChannel(uiMsg.channelID, uiMsg.channelType);
|
||||
if (uiMsg.getRemoteMsgExtra() == null) {
|
||||
uiMsg.setRemoteMsgExtra(new WKConversationMsgExtra());
|
||||
}
|
||||
uiMsg.getRemoteMsgExtra().browseTo = browseTo;
|
||||
WKIM.getInstance().getConversationManager().setOnRefreshMsg(uiMsg, true, "getSendBaseMsg");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (WKMediaMessageContent.class.isAssignableFrom(msg.baseContentMsgModel.getClass())) {
|
||||
//多媒体数据
|
||||
if (jsonObject.has("localPath")) {
|
||||
jsonObject.remove("localPath");
|
||||
}
|
||||
//视频地址
|
||||
if (jsonObject.has("videoLocalPath")) {
|
||||
jsonObject.remove("videoLocalPath");
|
||||
}
|
||||
}
|
||||
sendMsg.payload = jsonObject.toString();
|
||||
WKLoggerUtils.getInstance().e(jsonObject.toString());
|
||||
return sendMsg;
|
||||
}
|
||||
|
||||
WKMsg baseMsg2WKMsg(WKBaseMsg baseMsg) {
|
||||
WKReceivedMsg receivedMsg = (WKReceivedMsg) baseMsg;
|
||||
WKMsg msg = new WKMsg();
|
||||
msg.channelType = receivedMsg.channelType;
|
||||
msg.channelID = receivedMsg.channelID;
|
||||
msg.content = receivedMsg.payload;
|
||||
msg.messageID = receivedMsg.messageID;
|
||||
msg.messageSeq = receivedMsg.messageSeq;
|
||||
msg.timestamp = receivedMsg.messageTimestamp;
|
||||
msg.fromUID = receivedMsg.fromUID;
|
||||
msg.setting = receivedMsg.setting;
|
||||
msg.clientMsgNO = receivedMsg.clientMsgNo;
|
||||
msg.status = WKSendMsgResult.send_success;
|
||||
msg.topicID = receivedMsg.topicID;
|
||||
|
||||
msg.orderSeq = WKIM.getInstance().getMsgManager().getMessageOrderSeq(msg.messageSeq, msg.channelID, msg.channelType);
|
||||
msg.isDeleted = isDelete(msg.content);
|
||||
return msg;
|
||||
}
|
||||
|
||||
private static int isDelete(String contentJson) {
|
||||
int isDelete = 0;
|
||||
if (!TextUtils.isEmpty(contentJson)) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(contentJson);
|
||||
isDelete = WKIM.getInstance().getMsgManager().isDeletedMsg(jsonObject);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return isDelete;
|
||||
}
|
||||
}
|
@ -5,26 +5,23 @@ import android.text.TextUtils;
|
||||
import com.xinbida.wukongim.WKIM;
|
||||
import com.xinbida.wukongim.WKIMApplication;
|
||||
import com.xinbida.wukongim.db.ConversationDbManager;
|
||||
import com.xinbida.wukongim.db.WKDBColumns;
|
||||
import com.xinbida.wukongim.db.MsgDbManager;
|
||||
import com.xinbida.wukongim.db.WKDBColumns;
|
||||
import com.xinbida.wukongim.entity.WKChannelType;
|
||||
import com.xinbida.wukongim.entity.WKMsg;
|
||||
import com.xinbida.wukongim.entity.WKSyncMsg;
|
||||
import com.xinbida.wukongim.entity.WKUIConversationMsg;
|
||||
import com.xinbida.wukongim.interfaces.IReceivedMsgListener;
|
||||
import com.xinbida.wukongim.manager.CMDManager;
|
||||
import com.xinbida.wukongim.manager.ConversationManager;
|
||||
import com.xinbida.wukongim.entity.WKChannelType;
|
||||
import com.xinbida.wukongim.message.type.WKMsgContentType;
|
||||
import com.xinbida.wukongim.message.type.WKMsgType;
|
||||
import com.xinbida.wukongim.protocol.WKBaseMsg;
|
||||
import com.xinbida.wukongim.protocol.WKConnectAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKConnectMsg;
|
||||
import com.xinbida.wukongim.protocol.WKDisconnectMsg;
|
||||
import com.xinbida.wukongim.protocol.WKPingMsg;
|
||||
import com.xinbida.wukongim.protocol.WKPongMsg;
|
||||
import com.xinbida.wukongim.protocol.WKReceivedAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKSendAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKSendMsg;
|
||||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
@ -64,23 +61,9 @@ public class MessageHandler {
|
||||
if (msg == null) {
|
||||
return 1;
|
||||
}
|
||||
byte[] bytes;
|
||||
if (msg.packetType == WKMsgType.CONNECT) {
|
||||
// 连接
|
||||
bytes = MessageConvertHandler.getInstance().enConnectMsg((WKConnectMsg) msg);
|
||||
} else if (msg.packetType == WKMsgType.REVACK) {
|
||||
// 收到消息回执
|
||||
bytes = MessageConvertHandler.getInstance().enReceivedAckMsg((WKReceivedAckMsg) msg);
|
||||
} else if (msg.packetType == WKMsgType.SEND) {
|
||||
// 发送聊天消息
|
||||
bytes = MessageConvertHandler.getInstance().enSendMsg((WKSendMsg) msg);
|
||||
} else if (msg.packetType == WKMsgType.PING) {
|
||||
// 发送心跳
|
||||
bytes = MessageConvertHandler.getInstance().enPingMsg((WKPingMsg) msg);
|
||||
WKLoggerUtils.getInstance().e("ping...");
|
||||
} else {
|
||||
// 其他消息
|
||||
WKLoggerUtils.getInstance().e("发送未知消息类型");
|
||||
byte[] bytes = WKProto.getInstance().encodeMsg(msg);
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
WKLoggerUtils.getInstance().e("发送未知消息包:" + msg.packetType);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -154,13 +137,13 @@ public class MessageHandler {
|
||||
WKLoggerUtils.getInstance().e("消息包类型" + packetType);
|
||||
if (packetType == WKMsgType.PONG) {
|
||||
//心跳ack
|
||||
mIReceivedMsgListener.heartbeatMsg(new WKPongMsg());
|
||||
mIReceivedMsgListener.pongMsg(new WKPongMsg());
|
||||
WKLoggerUtils.getInstance().e("pong...");
|
||||
byte[] bytes = Arrays.copyOfRange(lastMsgBytes, 1, lastMsgBytes.length);
|
||||
cacheData = lastMsgBytes = bytes;
|
||||
} else {
|
||||
if (packetType < 10) {
|
||||
// TODO: 2019-12-21 计算剩余长度
|
||||
// 2019-12-21 计算剩余长度
|
||||
if (lastMsgBytes.length < 5) {
|
||||
cacheData = lastMsgBytes;
|
||||
break;
|
||||
@ -202,7 +185,7 @@ public class MessageHandler {
|
||||
|
||||
if (bytes != null && bytes.length > 0) {
|
||||
WKBaseMsg g_msg;
|
||||
g_msg = MessageConvertHandler.getInstance().decodeMessage(bytes);
|
||||
g_msg = WKProto.getInstance().decodeMessage(bytes);
|
||||
if (g_msg != null) {
|
||||
//连接ack
|
||||
if (g_msg.packetType == WKMsgType.CONNACK) {
|
||||
@ -228,7 +211,7 @@ public class MessageHandler {
|
||||
.sendAckMsg(talkSendStatus);
|
||||
} else if (g_msg.packetType == WKMsgType.RECVEIVED) {
|
||||
//收到消息
|
||||
WKMsg message = MessageConvertHandler.getInstance().baseMsg2WKMsg(g_msg);
|
||||
WKMsg message = WKProto.getInstance().baseMsg2WKMsg(g_msg);
|
||||
message.header.noPersist = no_persist == 1;
|
||||
message.header.redDot = red_dot == 1;
|
||||
message.header.syncOnce = sync_once == 1;
|
||||
@ -239,7 +222,7 @@ public class MessageHandler {
|
||||
WKDisconnectMsg disconnectMsg = (WKDisconnectMsg) g_msg;
|
||||
mIReceivedMsgListener.kickMsg(disconnectMsg);
|
||||
} else if (g_msg.packetType == WKMsgType.PONG) {
|
||||
mIReceivedMsgListener.heartbeatMsg((WKPongMsg) g_msg);
|
||||
mIReceivedMsgListener.pongMsg((WKPongMsg) g_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -284,7 +267,7 @@ public class MessageHandler {
|
||||
//回复消息ack
|
||||
private void sendAck(List<WKReceivedAckMsg> list) {
|
||||
if (list.size() == 1) {
|
||||
ConnectionHandler.getInstance().sendMessage(list.get(0));
|
||||
WKConnection.getInstance().sendMessage(list.get(0));
|
||||
return;
|
||||
}
|
||||
final Timer sendAckTimer = new Timer();
|
||||
@ -292,7 +275,7 @@ public class MessageHandler {
|
||||
@Override
|
||||
public void run() {
|
||||
if (list.size() > 0) {
|
||||
ConnectionHandler.getInstance().sendMessage(list.get(0));
|
||||
WKConnection.getInstance().sendMessage(list.get(0));
|
||||
list.remove(0);
|
||||
} else {
|
||||
sendAckTimer.cancel();
|
||||
@ -463,6 +446,4 @@ public class MessageHandler {
|
||||
public void updateLastSendingMsgFail() {
|
||||
MsgDbManager.getInstance().updateAllMsgSendFail();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -27,13 +27,12 @@ import com.xinbida.wukongim.msgmodel.WKVideoContent;
|
||||
import com.xinbida.wukongim.protocol.WKBaseMsg;
|
||||
import com.xinbida.wukongim.protocol.WKConnectMsg;
|
||||
import com.xinbida.wukongim.protocol.WKDisconnectMsg;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKMessageContent;
|
||||
import com.xinbida.wukongim.protocol.WKPingMsg;
|
||||
import com.xinbida.wukongim.protocol.WKPongMsg;
|
||||
import com.xinbida.wukongim.protocol.WKSendAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKSendMsg;
|
||||
import com.xinbida.wukongim.utils.DateUtils;
|
||||
import com.xinbida.wukongim.utils.FileUtils;
|
||||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
|
||||
import org.xsocket.connection.IConnection;
|
||||
@ -54,15 +53,15 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* 5/21/21 10:51 AM
|
||||
* IM connect
|
||||
*/
|
||||
public class ConnectionHandler {
|
||||
private ConnectionHandler() {
|
||||
public class WKConnection {
|
||||
private WKConnection() {
|
||||
}
|
||||
|
||||
private static class ConnectHandleBinder {
|
||||
private static final ConnectionHandler CONNECT = new ConnectionHandler();
|
||||
private static final WKConnection CONNECT = new WKConnection();
|
||||
}
|
||||
|
||||
public static ConnectionHandler getInstance() {
|
||||
public static WKConnection getInstance() {
|
||||
return ConnectHandleBinder.CONNECT;
|
||||
}
|
||||
|
||||
@ -76,12 +75,13 @@ public class ConnectionHandler {
|
||||
private String ip;
|
||||
private int port;
|
||||
volatile INonBlockingConnection connection;
|
||||
volatile ClientHandler clientHandler;
|
||||
volatile ConnectionClient connectionClient;
|
||||
private long requestIPTime;
|
||||
private final long requestIPTimeoutTime = 6;
|
||||
public String socketSingleID;
|
||||
private String lastRequestId;
|
||||
private final long reconnectDelay = 1500;
|
||||
private int unReceivePongCount = 0;
|
||||
public volatile Handler reconnectionHandler = new Handler(Objects.requireNonNull(Looper.myLooper()));
|
||||
|
||||
Runnable reconnectionRunnable = this::reconnection;
|
||||
@ -111,7 +111,7 @@ public class ConnectionHandler {
|
||||
requestIPTime = DateUtils.getInstance().getCurrentSeconds();
|
||||
getIPAndPort();
|
||||
} else {
|
||||
if (!ConnectionTimerHandler.getInstance().checkNetWorkTimerIsRunning) {
|
||||
if (!WKTimers.getInstance().checkNetWorkTimerIsRunning) {
|
||||
WKIM.getInstance().getConnectionManager().setConnectionStatus(WKConnectStatus.noNetwork, WKConnectReason.NoNetwork);
|
||||
isReConnecting = false;
|
||||
reconnectionHandler.postDelayed(reconnectionRunnable, reconnectDelay);
|
||||
@ -141,11 +141,11 @@ public class ConnectionHandler {
|
||||
reconnectionHandler.postDelayed(reconnectionRunnable, reconnectDelay);
|
||||
} else {
|
||||
if (lastRequestId.equals(requestId)) {
|
||||
ConnectionHandler.this.ip = ip;
|
||||
ConnectionHandler.this.port = port;
|
||||
WKConnection.this.ip = ip;
|
||||
WKConnection.this.port = port;
|
||||
WKLoggerUtils.getInstance().e("连接的IP和Port" + ip + ":" + port);
|
||||
if (connectionIsNull()) {
|
||||
new Thread(ConnectionHandler.this::connSocket).start();
|
||||
new Thread(WKConnection.this::connSocket).start();
|
||||
}
|
||||
} else {
|
||||
if (connectionIsNull()) {
|
||||
@ -161,9 +161,9 @@ public class ConnectionHandler {
|
||||
closeConnect();
|
||||
try {
|
||||
socketSingleID = UUID.randomUUID().toString().replace("-", "");
|
||||
clientHandler = new ClientHandler();
|
||||
connectionClient = new ConnectionClient();
|
||||
// InetAddress inetAddress = InetAddress.getByName(ip);
|
||||
connection = new NonBlockingConnection(ip, port, clientHandler);
|
||||
connection = new NonBlockingConnection(ip, port, connectionClient);
|
||||
connection.setAttachment(socketSingleID);
|
||||
connection.setIdleTimeoutMillis(1000 * 3);
|
||||
connection.setConnectionTimeoutMillis(1000 * 3);
|
||||
@ -185,7 +185,7 @@ public class ConnectionHandler {
|
||||
}
|
||||
|
||||
void receivedData(byte[] data) {
|
||||
MessageHandler.getInstance().cutBytes( data,
|
||||
MessageHandler.getInstance().cutBytes(data,
|
||||
new IReceivedMsgListener() {
|
||||
|
||||
public void sendAckMsg(
|
||||
@ -198,10 +198,6 @@ public class ConnectionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveMsg(WKMsg message) {
|
||||
// 收到在线消息,回服务器ack
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnect() {
|
||||
@ -215,9 +211,10 @@ public class ConnectionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void heartbeatMsg(WKPongMsg msgHeartbeat) {
|
||||
public void pongMsg(WKPongMsg msgHeartbeat) {
|
||||
// 心跳消息
|
||||
lastMsgTime = DateUtils.getInstance().getCurrentSeconds();
|
||||
unReceivePongCount = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -265,7 +262,7 @@ public class ConnectionHandler {
|
||||
if (status == WKConnectStatus.success) {
|
||||
//等待中
|
||||
connectStatus = WKConnectStatus.success;
|
||||
ConnectionTimerHandler.getInstance().startAll();
|
||||
WKTimers.getInstance().startAll();
|
||||
resendMsg();
|
||||
WKIM.getInstance().getConnectionManager().setConnectionStatus(WKConnectStatus.syncMsg, WKConnectReason.SyncMsg);
|
||||
// 判断同步模式
|
||||
@ -304,6 +301,9 @@ public class ConnectionHandler {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mBaseMsg.packetType == WKMsgType.PING) {
|
||||
unReceivePongCount++;
|
||||
}
|
||||
if (connection == null || !connection.isOpen()) {
|
||||
reconnection();
|
||||
return;
|
||||
@ -317,6 +317,10 @@ public class ConnectionHandler {
|
||||
|
||||
// 查看心跳是否超时
|
||||
void checkHeartIsTimeOut() {
|
||||
if (unReceivePongCount >= 5) {
|
||||
reconnectionHandler.postDelayed(reconnectionRunnable, reconnectDelay);
|
||||
return;
|
||||
}
|
||||
long nowTime = DateUtils.getInstance().getCurrentSeconds();
|
||||
if (nowTime - lastMsgTime >= 60) {
|
||||
sendMessage(new WKPingMsg());
|
||||
@ -441,7 +445,7 @@ public class ConnectionHandler {
|
||||
}
|
||||
|
||||
}
|
||||
WKBaseMsg base = MessageConvertHandler.getInstance().getSendBaseMsg(msg);
|
||||
WKBaseMsg base = WKProto.getInstance().getSendBaseMsg(msg);
|
||||
if (base != null && msg.clientSeq != 0) {
|
||||
msg.clientSeq = ((WKSendMsg) base).clientSeq;
|
||||
}
|
||||
@ -483,7 +487,7 @@ public class ConnectionHandler {
|
||||
if (isSuccess) {
|
||||
if (!sendingMsgHashMap.containsKey((int) msg.clientSeq)) {
|
||||
msg.baseContentMsgModel = messageContent;
|
||||
WKBaseMsg base1 = MessageConvertHandler.getInstance().getSendBaseMsg(msg);
|
||||
WKBaseMsg base1 = WKProto.getInstance().getSendBaseMsg(msg);
|
||||
addSendingMsg((WKSendMsg) base1);
|
||||
sendMessage(base1);
|
||||
}
|
||||
@ -494,7 +498,7 @@ public class ConnectionHandler {
|
||||
});
|
||||
} else {
|
||||
if (base != null) {
|
||||
if (msg.type != 9994) {
|
||||
if (msg.header != null && !msg.header.noPersist) {
|
||||
addSendingMsg((WKSendMsg) base);
|
||||
}
|
||||
sendMessage(base);
|
||||
@ -507,8 +511,8 @@ public class ConnectionHandler {
|
||||
}
|
||||
|
||||
public void stopAll() {
|
||||
clientHandler = null;
|
||||
ConnectionTimerHandler.getInstance().stopAll();
|
||||
connectionClient = null;
|
||||
WKTimers.getInstance().stopAll();
|
||||
closeConnect();
|
||||
connectStatus = WKConnectStatus.fail;
|
||||
isReConnecting = false;
|
408
wkim/src/main/java/com/xinbida/wukongim/message/WKProto.java
Normal file
408
wkim/src/main/java/com/xinbida/wukongim/message/WKProto.java
Normal file
@ -0,0 +1,408 @@
|
||||
package com.xinbida.wukongim.message;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.xinbida.wukongim.WKIM;
|
||||
import com.xinbida.wukongim.WKIMApplication;
|
||||
import com.xinbida.wukongim.db.MsgDbManager;
|
||||
import com.xinbida.wukongim.db.WKDBColumns;
|
||||
import com.xinbida.wukongim.entity.WKConversationMsgExtra;
|
||||
import com.xinbida.wukongim.entity.WKMsg;
|
||||
import com.xinbida.wukongim.entity.WKMsgSetting;
|
||||
import com.xinbida.wukongim.entity.WKUIConversationMsg;
|
||||
import com.xinbida.wukongim.message.type.WKMsgType;
|
||||
import com.xinbida.wukongim.message.type.WKSendMsgResult;
|
||||
import com.xinbida.wukongim.msgmodel.WKMediaMessageContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKMessageContent;
|
||||
import com.xinbida.wukongim.msgmodel.WKMsgEntity;
|
||||
import com.xinbida.wukongim.protocol.WKBaseMsg;
|
||||
import com.xinbida.wukongim.protocol.WKConnectAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKConnectMsg;
|
||||
import com.xinbida.wukongim.protocol.WKDisconnectMsg;
|
||||
import com.xinbida.wukongim.protocol.WKPingMsg;
|
||||
import com.xinbida.wukongim.protocol.WKPongMsg;
|
||||
import com.xinbida.wukongim.protocol.WKReceivedAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKReceivedMsg;
|
||||
import com.xinbida.wukongim.protocol.WKSendAckMsg;
|
||||
import com.xinbida.wukongim.protocol.WKSendMsg;
|
||||
import com.xinbida.wukongim.utils.CryptoUtils;
|
||||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* 5/21/21 11:28 AM
|
||||
* 收发消息转换
|
||||
*/
|
||||
class WKProto {
|
||||
|
||||
private WKProto() {
|
||||
}
|
||||
|
||||
private static class MessageConvertHandlerBinder {
|
||||
static final WKProto msgConvert = new WKProto();
|
||||
}
|
||||
|
||||
public static WKProto getInstance() {
|
||||
return MessageConvertHandlerBinder.msgConvert;
|
||||
}
|
||||
|
||||
byte[] encodeMsg(WKBaseMsg msg) {
|
||||
byte[] bytes = null;
|
||||
if (msg.packetType == WKMsgType.CONNECT) {
|
||||
// 连接
|
||||
bytes = WKProto.getInstance().enConnectMsg((WKConnectMsg) msg);
|
||||
} else if (msg.packetType == WKMsgType.REVACK) {
|
||||
// 收到消息回执
|
||||
bytes = WKProto.getInstance().enReceivedAckMsg((WKReceivedAckMsg) msg);
|
||||
} else if (msg.packetType == WKMsgType.SEND) {
|
||||
// 发送聊天消息
|
||||
bytes = WKProto.getInstance().enSendMsg((WKSendMsg) msg);
|
||||
} else if (msg.packetType == WKMsgType.PING) {
|
||||
// 发送心跳
|
||||
bytes = WKProto.getInstance().enPingMsg((WKPingMsg) msg);
|
||||
WKLoggerUtils.getInstance().e("ping...");
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
byte[] enConnectMsg(WKConnectMsg connectMsg) {
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(connectMsg.getRemainingLength());
|
||||
int totalLen = connectMsg.getTotalLen();
|
||||
WKWrite wkWrite = new WKWrite(totalLen);
|
||||
try {
|
||||
wkWrite.writeByte(WKTypeUtils.getInstance().getHeader(connectMsg.packetType, connectMsg.flag, 0, 0));
|
||||
wkWrite.writeBytes(remainingBytes);
|
||||
wkWrite.writeByte(connectMsg.protocolVersion);
|
||||
wkWrite.writeByte(connectMsg.deviceFlag);
|
||||
wkWrite.writeString(connectMsg.deviceID);
|
||||
wkWrite.writeString(WKIMApplication.getInstance().getUid());
|
||||
wkWrite.writeString(WKIMApplication.getInstance().getToken());
|
||||
wkWrite.writeLong(connectMsg.clientTimestamp);
|
||||
wkWrite.writeString(CryptoUtils.getInstance().getPublicKey());
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return wkWrite.getWriteBytes();
|
||||
}
|
||||
|
||||
synchronized byte[] enReceivedAckMsg(WKReceivedAckMsg receivedAckMsg) {
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(8 + 4);
|
||||
|
||||
int totalLen = 1 + remainingBytes.length + 8 + 4;
|
||||
WKWrite wkWrite = new WKWrite(totalLen);
|
||||
wkWrite.writeByte(WKTypeUtils.getInstance().getHeader(receivedAckMsg.packetType, receivedAckMsg.no_persist ? 1 : 0, receivedAckMsg.red_dot ? 1 : 0, receivedAckMsg.sync_once ? 1 : 0));
|
||||
wkWrite.writeBytes(remainingBytes);
|
||||
BigInteger bigInteger = new BigInteger(receivedAckMsg.messageID);
|
||||
wkWrite.writeLong(bigInteger.longValue());
|
||||
wkWrite.writeInt(receivedAckMsg.messageSeq);
|
||||
return wkWrite.getWriteBytes();
|
||||
}
|
||||
|
||||
byte[] enPingMsg(WKPingMsg pingMsg) {
|
||||
WKWrite wkWrite = new WKWrite(1);
|
||||
wkWrite.writeByte(WKTypeUtils.getInstance().getHeader(pingMsg.packetType, pingMsg.flag, 0, 0));
|
||||
return wkWrite.getWriteBytes();
|
||||
}
|
||||
|
||||
byte[] enSendMsg(WKSendMsg sendMsg) {
|
||||
// 先加密内容
|
||||
String sendContent = sendMsg.getSendContent();
|
||||
String msgKeyContent = sendMsg.getMsgKey();
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(sendMsg.getRemainingLength());
|
||||
int totalLen = sendMsg.getTotalLength();
|
||||
WKWrite wkWrite = new WKWrite(totalLen);
|
||||
try {
|
||||
wkWrite.writeByte(WKTypeUtils.getInstance().getHeader(sendMsg.packetType, sendMsg.no_persist ? 1 : 0, sendMsg.red_dot ? 1 : 0, sendMsg.sync_once ? 1 : 0));
|
||||
wkWrite.writeBytes(remainingBytes);
|
||||
wkWrite.writeByte(WKTypeUtils.getInstance().getMsgSetting(sendMsg.setting));
|
||||
wkWrite.writeInt(sendMsg.clientSeq);
|
||||
wkWrite.writeString(sendMsg.clientMsgNo);
|
||||
wkWrite.writeString(sendMsg.channelId);
|
||||
wkWrite.writeByte(sendMsg.channelType);
|
||||
wkWrite.writeString(msgKeyContent);
|
||||
if (sendMsg.setting.topic == 1) {
|
||||
wkWrite.writeString(sendMsg.topicID);
|
||||
}
|
||||
wkWrite.writePayload(sendContent);
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return wkWrite.getWriteBytes();
|
||||
}
|
||||
|
||||
private WKConnectAckMsg deConnectAckMsg(WKRead wkRead) {
|
||||
WKConnectAckMsg connectAckMsg = new WKConnectAckMsg();
|
||||
try {
|
||||
long time = wkRead.readLong();
|
||||
short reasonCode = wkRead.readByte();
|
||||
String serverKey = wkRead.readString();
|
||||
String salt = wkRead.readString();
|
||||
connectAckMsg.serverKey = serverKey;
|
||||
connectAckMsg.salt = salt;
|
||||
//保存公钥和安全码
|
||||
CryptoUtils.getInstance().setServerKeyAndSalt(connectAckMsg.serverKey, connectAckMsg.salt);
|
||||
connectAckMsg.timeDiff = time;
|
||||
connectAckMsg.reasonCode = reasonCode;
|
||||
} catch (IOException e) {
|
||||
WKLoggerUtils.getInstance().d("解码连接ack错误");
|
||||
}
|
||||
|
||||
return connectAckMsg;
|
||||
}
|
||||
|
||||
private WKSendAckMsg deSendAckMsg(WKRead wkRead) {
|
||||
WKSendAckMsg sendAckMsg = new WKSendAckMsg();
|
||||
try {
|
||||
sendAckMsg.messageID = wkRead.readMsgID();
|
||||
sendAckMsg.clientSeq = wkRead.readInt();
|
||||
sendAckMsg.messageSeq = wkRead.readInt();
|
||||
sendAckMsg.reasonCode = wkRead.readByte();
|
||||
WKLoggerUtils.getInstance().e("发送返回状态:" + sendAckMsg.reasonCode);
|
||||
} catch (IOException e) {
|
||||
WKLoggerUtils.getInstance().e("解码发送消息ack错误");
|
||||
}
|
||||
return sendAckMsg;
|
||||
}
|
||||
|
||||
private WKDisconnectMsg deDisconnectMsg(WKRead wkRead) {
|
||||
WKDisconnectMsg disconnectMsg = new WKDisconnectMsg();
|
||||
try {
|
||||
disconnectMsg.reasonCode = wkRead.readByte();
|
||||
disconnectMsg.reason = wkRead.readString();
|
||||
WKLoggerUtils.getInstance().e("sdk收到被踢的消息code:" + disconnectMsg.reasonCode + ",reason:" + disconnectMsg.reason);
|
||||
return disconnectMsg;
|
||||
|
||||
} catch (IOException e) {
|
||||
WKLoggerUtils.getInstance().e("解码断开连接错误");
|
||||
}
|
||||
return disconnectMsg;
|
||||
}
|
||||
|
||||
private WKReceivedMsg deReceivedMsg(WKRead wkRead) {
|
||||
WKReceivedMsg receivedMsg = new WKReceivedMsg();
|
||||
try {
|
||||
byte settingByte = wkRead.readByte();
|
||||
receivedMsg.setting = WKTypeUtils.getInstance().getMsgSetting(settingByte);
|
||||
receivedMsg.msgKey = wkRead.readString();
|
||||
receivedMsg.fromUID = wkRead.readString();
|
||||
receivedMsg.channelID = wkRead.readString();
|
||||
receivedMsg.channelType = wkRead.readByte();
|
||||
receivedMsg.clientMsgNo = wkRead.readString();
|
||||
if (receivedMsg.setting.stream == 1) {
|
||||
receivedMsg.streamNO = wkRead.readString();
|
||||
receivedMsg.streamSeq = wkRead.readInt();
|
||||
receivedMsg.streamFlag = wkRead.readByte();
|
||||
}
|
||||
receivedMsg.messageID = wkRead.readMsgID();
|
||||
receivedMsg.messageSeq = wkRead.readInt();
|
||||
receivedMsg.messageTimestamp = wkRead.readInt();
|
||||
if (receivedMsg.setting.topic == 1) {
|
||||
receivedMsg.topicID = wkRead.readString();
|
||||
}
|
||||
String content = wkRead.readPayload();
|
||||
receivedMsg.payload = CryptoUtils.getInstance().aesDecrypt(CryptoUtils.getInstance().base64Decode(content));
|
||||
String msgKey = receivedMsg.messageID
|
||||
+ receivedMsg.messageSeq
|
||||
+ receivedMsg.clientMsgNo
|
||||
+ receivedMsg.messageTimestamp
|
||||
+ receivedMsg.fromUID
|
||||
+ receivedMsg.channelID
|
||||
+ receivedMsg.channelType
|
||||
+ content;
|
||||
byte[] result = CryptoUtils.getInstance().aesEncrypt(msgKey);
|
||||
String base64Result = CryptoUtils.getInstance().base64Encode(result);
|
||||
String localMsgKey = CryptoUtils.getInstance().digestMD5(base64Result);
|
||||
if (!localMsgKey.equals(receivedMsg.msgKey)) {
|
||||
return null;
|
||||
}
|
||||
WKLoggerUtils.getInstance().e("接受到消息:" + receivedMsg.payload);
|
||||
} catch (IOException e) {
|
||||
WKLoggerUtils.getInstance().e("解码收到消息错误");
|
||||
}
|
||||
return receivedMsg;
|
||||
}
|
||||
|
||||
WKBaseMsg decodeMessage(byte[] bytes) {
|
||||
try {
|
||||
WKRead wkRead = new WKRead(bytes);
|
||||
int packetType = wkRead.readPacketType();
|
||||
wkRead.readRemainingLength();
|
||||
if (packetType == WKMsgType.CONNACK) {
|
||||
return deConnectAckMsg(wkRead);
|
||||
} else if (packetType == WKMsgType.SENDACK) {
|
||||
return deSendAckMsg(wkRead);
|
||||
} else if (packetType == WKMsgType.DISCONNECT) {
|
||||
return deDisconnectMsg(wkRead);
|
||||
} else if (packetType == WKMsgType.RECVEIVED) {
|
||||
return deReceivedMsg(wkRead);
|
||||
} else if (packetType == WKMsgType.PONG) {
|
||||
return new WKPongMsg();
|
||||
} else {
|
||||
WKLoggerUtils.getInstance().e("解析协议类型失败--->:" + packetType);
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
WKLoggerUtils.getInstance().e("解析数据异常------>:" + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发送的消息
|
||||
*
|
||||
* @param msg 本地消息
|
||||
* @return 网络消息
|
||||
*/
|
||||
WKBaseMsg getSendBaseMsg(WKMsg msg) {
|
||||
//发送消息
|
||||
JSONObject jsonObject = null;
|
||||
if (msg.baseContentMsgModel != null) {
|
||||
jsonObject = msg.baseContentMsgModel.encodeMsg();
|
||||
} else {
|
||||
msg.baseContentMsgModel = new WKMessageContent();
|
||||
}
|
||||
try {
|
||||
if (jsonObject == null) jsonObject = new JSONObject();
|
||||
if (!jsonObject.has(WKDBColumns.WKMessageColumns.from_uid)) {
|
||||
jsonObject.put(WKDBColumns.WKMessageColumns.from_uid, WKIMApplication.getInstance().getUid());
|
||||
}
|
||||
jsonObject.put(WKDBColumns.WKMessageColumns.type, msg.type);
|
||||
//判断@情况
|
||||
if (msg.baseContentMsgModel.mentionInfo != null
|
||||
&& msg.baseContentMsgModel.mentionInfo.uids != null
|
||||
&& msg.baseContentMsgModel.mentionInfo.uids.size() > 0) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (int i = 0, size = msg.baseContentMsgModel.mentionInfo.uids.size(); i < size; i++) {
|
||||
jsonArray.put(msg.baseContentMsgModel.mentionInfo.uids.get(i));
|
||||
}
|
||||
if (!jsonObject.has("mention")) {
|
||||
JSONObject mentionJson = new JSONObject();
|
||||
mentionJson.put("all", msg.baseContentMsgModel.mentionAll);
|
||||
mentionJson.put("uids", jsonArray);
|
||||
jsonObject.put("mention", mentionJson);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (msg.baseContentMsgModel.mentionAll == 1) {
|
||||
JSONObject mentionJson = new JSONObject();
|
||||
mentionJson.put("all", msg.baseContentMsgModel.mentionAll);
|
||||
jsonObject.put("mention", mentionJson);
|
||||
}
|
||||
}
|
||||
// 被回复消息
|
||||
if (msg.baseContentMsgModel.reply != null) {
|
||||
jsonObject.put("reply", msg.baseContentMsgModel.reply.encodeMsg());
|
||||
}
|
||||
// 机器人ID
|
||||
if (!TextUtils.isEmpty(msg.baseContentMsgModel.robotID)) {
|
||||
jsonObject.put("robot_id", msg.baseContentMsgModel.robotID);
|
||||
}
|
||||
if (msg.baseContentMsgModel.entities != null && msg.baseContentMsgModel.entities.size() > 0) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (WKMsgEntity entity : msg.baseContentMsgModel.entities) {
|
||||
JSONObject jo = new JSONObject();
|
||||
jo.put("offset", entity.offset);
|
||||
jo.put("length", entity.length);
|
||||
jo.put("type", entity.type);
|
||||
jo.put("value", entity.value);
|
||||
jsonArray.put(jo);
|
||||
}
|
||||
jsonObject.put("entities", jsonArray);
|
||||
}
|
||||
if (msg.baseContentMsgModel.flame != 0) {
|
||||
jsonObject.put("flame_second", msg.baseContentMsgModel.flameSecond);
|
||||
jsonObject.put("flame", msg.baseContentMsgModel.flame);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
WKSendMsg sendMsg = new WKSendMsg();
|
||||
// 默认先设置clientSeq,因为有可能本条消息并不需要入库,UI上自己设置了clientSeq
|
||||
sendMsg.clientSeq = (int) msg.clientSeq;
|
||||
sendMsg.sync_once = msg.header.syncOnce;
|
||||
sendMsg.no_persist = msg.header.noPersist;
|
||||
sendMsg.red_dot = msg.header.redDot;
|
||||
sendMsg.clientMsgNo = msg.clientMsgNO;
|
||||
sendMsg.channelId = msg.channelID;
|
||||
sendMsg.channelType = msg.channelType;
|
||||
sendMsg.topicID = msg.topicID;
|
||||
if (msg.setting == null) msg.setting = new WKMsgSetting();
|
||||
sendMsg.setting = msg.setting;
|
||||
msg.content = jsonObject.toString();
|
||||
long tempOrderSeq = MsgDbManager.getInstance().queryMaxOrderSeqWithChannel(msg.channelID, msg.channelType);
|
||||
msg.orderSeq = tempOrderSeq + 1;
|
||||
// 需要存储的消息入库后更改消息的clientSeq
|
||||
if (!sendMsg.no_persist) {
|
||||
sendMsg.clientSeq = (int) (msg.clientSeq = (int) MsgDbManager.getInstance().insert(msg));
|
||||
if (msg.clientSeq > 0) {
|
||||
// 2022/4/27
|
||||
WKUIConversationMsg uiMsg = WKIM.getInstance().getConversationManager().updateWithWKMsg(msg);
|
||||
if (uiMsg != null) {
|
||||
long browseTo = WKIM.getInstance().getMsgManager().getMaxMessageSeqWithChannel(uiMsg.channelID, uiMsg.channelType);
|
||||
if (uiMsg.getRemoteMsgExtra() == null) {
|
||||
uiMsg.setRemoteMsgExtra(new WKConversationMsgExtra());
|
||||
}
|
||||
uiMsg.getRemoteMsgExtra().browseTo = browseTo;
|
||||
WKIM.getInstance().getConversationManager().setOnRefreshMsg(uiMsg, true, "getSendBaseMsg");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (WKMediaMessageContent.class.isAssignableFrom(msg.baseContentMsgModel.getClass())) {
|
||||
//多媒体数据
|
||||
if (jsonObject.has("localPath")) {
|
||||
jsonObject.remove("localPath");
|
||||
}
|
||||
//视频地址
|
||||
if (jsonObject.has("videoLocalPath")) {
|
||||
jsonObject.remove("videoLocalPath");
|
||||
}
|
||||
}
|
||||
sendMsg.payload = jsonObject.toString();
|
||||
WKLoggerUtils.getInstance().e(jsonObject.toString());
|
||||
return sendMsg;
|
||||
}
|
||||
|
||||
WKMsg baseMsg2WKMsg(WKBaseMsg baseMsg) {
|
||||
WKReceivedMsg receivedMsg = (WKReceivedMsg) baseMsg;
|
||||
WKMsg msg = new WKMsg();
|
||||
msg.channelType = receivedMsg.channelType;
|
||||
msg.channelID = receivedMsg.channelID;
|
||||
msg.content = receivedMsg.payload;
|
||||
msg.messageID = receivedMsg.messageID;
|
||||
msg.messageSeq = receivedMsg.messageSeq;
|
||||
msg.timestamp = receivedMsg.messageTimestamp;
|
||||
msg.fromUID = receivedMsg.fromUID;
|
||||
msg.setting = receivedMsg.setting;
|
||||
msg.clientMsgNO = receivedMsg.clientMsgNo;
|
||||
msg.status = WKSendMsgResult.send_success;
|
||||
msg.topicID = receivedMsg.topicID;
|
||||
|
||||
msg.orderSeq = WKIM.getInstance().getMsgManager().getMessageOrderSeq(msg.messageSeq, msg.channelID, msg.channelType);
|
||||
msg.isDeleted = isDelete(msg.content);
|
||||
return msg;
|
||||
}
|
||||
|
||||
private int isDelete(String contentJson) {
|
||||
int isDelete = 0;
|
||||
if (!TextUtils.isEmpty(contentJson)) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(contentJson);
|
||||
isDelete = WKIM.getInstance().getMsgManager().isDeletedMsg(jsonObject);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return isDelete;
|
||||
}
|
||||
}
|
82
wkim/src/main/java/com/xinbida/wukongim/message/WKRead.java
Normal file
82
wkim/src/main/java/com/xinbida/wukongim/message/WKRead.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.xinbida.wukongim.message;
|
||||
|
||||
import com.xinbida.wukongim.utils.BigTypeUtils;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class WKRead {
|
||||
InputStream inputStream;
|
||||
|
||||
WKRead(byte[] bytes) {
|
||||
this.inputStream = new ByteArrayInputStream(bytes);
|
||||
}
|
||||
|
||||
public int readPacketType() throws IOException {
|
||||
byte[] header = new byte[1];
|
||||
int headerRead = inputStream.read(header);
|
||||
if (headerRead == -1) return 0;
|
||||
return WKTypeUtils.getInstance().getHeight4(header[0]);
|
||||
}
|
||||
|
||||
public int readRemainingLength() {
|
||||
return WKTypeUtils.getInstance().bytes2Length(inputStream);
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
byte[] longByte = new byte[8];
|
||||
int read = inputStream.read(longByte);
|
||||
if (read == -1) return 0;
|
||||
return BigTypeUtils.getInstance().bytesToLong(longByte);
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
byte[] intByte = new byte[4];
|
||||
int read = inputStream.read(intByte);
|
||||
if (read == -1) return 0;
|
||||
return BigTypeUtils.getInstance().bytesToInt(intByte);
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
byte[] b = new byte[1];
|
||||
int read = inputStream.read(b);
|
||||
if (read == -1) return 0;
|
||||
return b[0];
|
||||
}
|
||||
|
||||
public String readString() throws IOException {
|
||||
byte[] strLengthByte = new byte[2];
|
||||
int read = inputStream.read(strLengthByte);
|
||||
if (read == -1) return "";
|
||||
int strLength = BigTypeUtils.getInstance().byteToShort(strLengthByte);
|
||||
byte[] strByte = new byte[strLength];
|
||||
read = inputStream.read(strByte);
|
||||
if (read == -1) return "";
|
||||
return WKTypeUtils.getInstance().bytesToString(strByte);
|
||||
}
|
||||
|
||||
public String readMsgID() throws IOException {
|
||||
String messageID;
|
||||
byte[] messageIdByte = new byte[8];
|
||||
int read = inputStream.read(messageIdByte);
|
||||
if (read == -1) return "";
|
||||
BigInteger bigInteger = new BigInteger(messageIdByte);
|
||||
if (bigInteger.toString().startsWith("-")) {
|
||||
BigInteger temp = new BigInteger("18446744073709551616");
|
||||
messageID = temp.add(bigInteger).toString();
|
||||
} else
|
||||
messageID = bigInteger.toString();
|
||||
return messageID;
|
||||
}
|
||||
|
||||
public String readPayload() throws IOException {
|
||||
int payloadLength = inputStream.available();
|
||||
byte[] payload = new byte[payloadLength];
|
||||
int read = inputStream.read(payload);
|
||||
if (read == -1) return "";
|
||||
return WKTypeUtils.getInstance().bytesToString(payload);
|
||||
}
|
||||
}
|
@ -13,15 +13,15 @@ import java.util.TimerTask;
|
||||
/**
|
||||
* 5/21/21 11:19 AM
|
||||
*/
|
||||
class ConnectionTimerHandler {
|
||||
private ConnectionTimerHandler() {
|
||||
class WKTimers {
|
||||
private WKTimers() {
|
||||
}
|
||||
|
||||
private static class ConnectionTimerHandlerBinder {
|
||||
static final ConnectionTimerHandler timeHandle = new ConnectionTimerHandler();
|
||||
static final WKTimers timeHandle = new WKTimers();
|
||||
}
|
||||
|
||||
public static ConnectionTimerHandler getInstance() {
|
||||
public static WKTimers getInstance() {
|
||||
return ConnectionTimerHandlerBinder.timeHandle;
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ class ConnectionTimerHandler {
|
||||
@Override
|
||||
public void run() {
|
||||
//发送心跳
|
||||
ConnectionHandler.getInstance().sendMessage(new WKPingMsg());
|
||||
WKConnection.getInstance().sendMessage(new WKPingMsg());
|
||||
}
|
||||
}, 0, heart_time * 1000);
|
||||
}
|
||||
@ -99,10 +99,10 @@ class ConnectionTimerHandler {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (ConnectionHandler.getInstance().connection == null || heartBeatTimer == null) {
|
||||
ConnectionHandler.getInstance().reconnection();
|
||||
if (WKConnection.getInstance().connection == null || heartBeatTimer == null) {
|
||||
WKConnection.getInstance().reconnection();
|
||||
}
|
||||
ConnectionHandler.getInstance().checkHeartIsTimeOut();
|
||||
WKConnection.getInstance().checkHeartIsTimeOut();
|
||||
}
|
||||
}, 1000 * 7, 1000 * 7);
|
||||
}
|
||||
@ -119,14 +119,14 @@ class ConnectionTimerHandler {
|
||||
if (!is_have_network) {
|
||||
WKIM.getInstance().getConnectionManager().setConnectionStatus(WKConnectStatus.noNetwork, WKConnectReason.NoNetwork);
|
||||
WKLoggerUtils.getInstance().e("无网络连接...");
|
||||
ConnectionHandler.getInstance().checkSendingMsg();
|
||||
WKConnection.getInstance().checkSendingMsg();
|
||||
} else {
|
||||
//有网络
|
||||
if (ConnectionHandler.getInstance().connectionIsNull())
|
||||
ConnectionHandler.getInstance().reconnection();
|
||||
if (WKConnection.getInstance().connectionIsNull())
|
||||
WKConnection.getInstance().reconnection();
|
||||
}
|
||||
if (ConnectionHandler.getInstance().connection == null || !ConnectionHandler.getInstance().connection.isOpen()) {
|
||||
ConnectionHandler.getInstance().reconnection();
|
||||
if (WKConnection.getInstance().connection == null || !WKConnection.getInstance().connection.isOpen()) {
|
||||
WKConnection.getInstance().reconnection();
|
||||
}
|
||||
checkNetWorkTimerIsRunning = true;
|
||||
}
|
54
wkim/src/main/java/com/xinbida/wukongim/message/WKWrite.java
Normal file
54
wkim/src/main/java/com/xinbida/wukongim/message/WKWrite.java
Normal file
@ -0,0 +1,54 @@
|
||||
package com.xinbida.wukongim.message;
|
||||
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class WKWrite {
|
||||
private final ByteBuffer buffer;
|
||||
private final byte[] bytes;
|
||||
|
||||
public WKWrite(int totalLength) {
|
||||
buffer = ByteBuffer.allocate(totalLength).order(
|
||||
ByteOrder.BIG_ENDIAN);
|
||||
bytes = new byte[totalLength];
|
||||
}
|
||||
|
||||
public void writeByte(byte b) {
|
||||
buffer.put(b);
|
||||
}
|
||||
|
||||
public void writeBytes(byte[] bytes) {
|
||||
buffer.put(bytes);
|
||||
}
|
||||
|
||||
public void writeInt(int v) {
|
||||
buffer.putInt(v);
|
||||
}
|
||||
|
||||
public void writeShort(int v) {
|
||||
buffer.putShort((short) v);
|
||||
}
|
||||
|
||||
public void writeLong(long v) {
|
||||
buffer.putLong(v);
|
||||
}
|
||||
|
||||
public void writeString(String v) throws UnsupportedEncodingException {
|
||||
buffer.putShort((short) v.length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(v));
|
||||
}
|
||||
|
||||
public void writePayload(String v) throws UnsupportedEncodingException {
|
||||
byte[] contentBytes = WKTypeUtils.getInstance().stringToByte(v);
|
||||
buffer.put(contentBytes);
|
||||
}
|
||||
|
||||
public byte[] getWriteBytes() {
|
||||
buffer.position(0);
|
||||
buffer.get(bytes);
|
||||
return bytes;
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.xinbida.wukongim.message.type.WKMsgContentType;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -2,8 +2,6 @@ package com.xinbida.wukongim.msgmodel;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
|
||||
/**
|
||||
* 2020-04-04 10:39
|
||||
* 多媒体消息。如果自定义消息带附件需继承该类
|
||||
|
@ -1,10 +1,9 @@
|
||||
package com.xinbida.wukongim.protocol;
|
||||
package com.xinbida.wukongim.msgmodel;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.xinbida.wukongim.entity.WKMentionInfo;
|
||||
import com.xinbida.wukongim.msgmodel.WKReply;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.xinbida.wukongim.protocol;
|
||||
package com.xinbida.wukongim.msgmodel;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
@ -4,7 +4,6 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.xinbida.wukongim.manager.MsgManager;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -5,7 +5,6 @@ import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.xinbida.wukongim.message.type.WKMsgContentType;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -4,7 +4,6 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.xinbida.wukongim.message.type.WKMsgContentType;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -4,7 +4,6 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.xinbida.wukongim.message.type.WKMsgContentType;
|
||||
import com.xinbida.wukongim.protocol.WKMessageContent;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -11,8 +11,6 @@ public class WKConnectAckMsg extends WKBaseMsg {
|
||||
public long timeDiff;
|
||||
//连接原因码
|
||||
public short reasonCode;
|
||||
//时间戳长度
|
||||
public long timeDiffLength = 8;
|
||||
// 服务端公钥
|
||||
public String serverKey;
|
||||
// 安全码
|
||||
|
@ -3,7 +3,9 @@ package com.xinbida.wukongim.protocol;
|
||||
|
||||
import com.xinbida.wukongim.WKIMApplication;
|
||||
import com.xinbida.wukongim.message.type.WKMsgType;
|
||||
import com.xinbida.wukongim.utils.CryptoUtils;
|
||||
import com.xinbida.wukongim.utils.DateUtils;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
/**
|
||||
* 2019-11-11 10:22
|
||||
@ -42,4 +44,34 @@ public class WKConnectMsg extends WKBaseMsg {
|
||||
deviceID = WKIMApplication.getInstance().getDeviceId();
|
||||
remainingLength = 1 + 1 + 8;//(协议版本号+设备标示(同标示同账号互踢)+客户端当前时间戳(13位时间戳,到毫秒))
|
||||
}
|
||||
|
||||
public int getRemainingLength() {
|
||||
remainingLength = getFixedHeaderLength()
|
||||
+ deviceIDLength
|
||||
+ deviceID.length()
|
||||
+ uidLength
|
||||
+ WKIMApplication.getInstance().getUid().length()
|
||||
+ tokenLength
|
||||
+ WKIMApplication.getInstance().getToken().length()
|
||||
+ clientTimeStampLength
|
||||
+ clientKeyLength
|
||||
+ CryptoUtils.getInstance().getPublicKey().length();
|
||||
return remainingLength;
|
||||
}
|
||||
|
||||
public int getTotalLen() {
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(getRemainingLength());
|
||||
return 1 + remainingBytes.length
|
||||
+ protocolVersionLength
|
||||
+ deviceFlagLength
|
||||
+ deviceIDLength
|
||||
+ deviceID.length()
|
||||
+ uidLength
|
||||
+ WKIMApplication.getInstance().getUid().length()
|
||||
+ tokenLength
|
||||
+ WKIMApplication.getInstance().getToken().length()
|
||||
+ clientTimeStampLength
|
||||
+ clientKeyLength
|
||||
+ CryptoUtils.getInstance().getPublicKey().length();
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,6 @@ public class WKReceivedAckMsg extends WKBaseMsg {
|
||||
public String messageID;
|
||||
//序列号
|
||||
public int messageSeq;
|
||||
//消息id长度
|
||||
public char messageIDLength = 2;
|
||||
|
||||
public WKReceivedAckMsg() {
|
||||
packetType = WKMsgType.REVACK;
|
||||
remainingLength = 8;//序列号
|
||||
|
@ -30,8 +30,53 @@ public class WKReceivedMsg extends WKBaseMsg {
|
||||
public String msgKey;
|
||||
// 消息设置
|
||||
public WKMsgSetting setting;
|
||||
public String streamNO;
|
||||
public int streamSeq;
|
||||
public int streamFlag;
|
||||
|
||||
private final int settingLength = 1;
|
||||
private final int msgKeyLength = 2;
|
||||
public int msgKeyContentLength = 0;
|
||||
private final int fromUIDLength = 2;
|
||||
public int fromUIDContentLength = 0;
|
||||
private final int channelTDLength = 2;
|
||||
public int channelTDContentLength = 0;
|
||||
private final int channelTypeLength = 1;
|
||||
private final int clientMsgNoLength = 2;
|
||||
public int clientMsgNoContentLength = 0;
|
||||
private final int streamNOLength = 2;
|
||||
public int streamNOContentLength = 0;
|
||||
public int streamSeqLength = 4;
|
||||
public int streamFlagLength = 1;
|
||||
private final int messageIDLength = 8;
|
||||
private final int messageSeqLength = 4;
|
||||
private final int messageTimeLength = 4;
|
||||
private final int topicIDLength = 2;
|
||||
public int topicIDContentLength = 0;
|
||||
|
||||
public WKReceivedMsg() {
|
||||
packetType = WKMsgType.RECVEIVED;
|
||||
}
|
||||
|
||||
public int getPayloadLength(int remainingLength) {
|
||||
int length = 0;
|
||||
length += settingLength;
|
||||
length += (msgKeyLength + msgKeyContentLength);
|
||||
length += (fromUIDLength + fromUIDContentLength);
|
||||
length += (channelTDLength + channelTDContentLength);
|
||||
length += channelTypeLength;
|
||||
length += (clientMsgNoLength + clientMsgNoContentLength);
|
||||
if (setting.stream == 1) {
|
||||
length += (streamNOLength + streamNOContentLength);
|
||||
length += streamSeqLength;
|
||||
length += streamFlagLength;
|
||||
}
|
||||
length += messageIDLength;
|
||||
length += messageSeqLength;
|
||||
length += messageTimeLength;
|
||||
if (setting.topic == 1) {
|
||||
length += (topicIDLength + topicIDContentLength);
|
||||
}
|
||||
return remainingLength - length;
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,6 @@ public class WKSendAckMsg extends WKBaseMsg {
|
||||
public long messageSeq;
|
||||
//发送原因代码 1表示成功
|
||||
public byte reasonCode;
|
||||
//客户端序号长度
|
||||
public int clientSeqLength = 4;
|
||||
|
||||
public WKSendAckMsg() {
|
||||
packetType = WKMsgType.SENDACK;
|
||||
|
@ -1,12 +1,16 @@
|
||||
package com.xinbida.wukongim.protocol;
|
||||
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.xinbida.wukongim.entity.WKMsgSetting;
|
||||
import com.xinbida.wukongim.message.type.WKMsgType;
|
||||
import com.xinbida.wukongim.utils.CryptoUtils;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
/**
|
||||
* 2019-11-11 10:30
|
||||
* 发送消息到talkservice
|
||||
* send 包
|
||||
*/
|
||||
public class WKSendMsg extends WKBaseMsg {
|
||||
//客户端消息序列号(由客户端生成,每个客户端唯一)
|
||||
@ -25,27 +29,84 @@ public class WKSendMsg extends WKBaseMsg {
|
||||
public int clientSeqLength = 4;
|
||||
//频道所占长度
|
||||
public short channelIdLength = 2;
|
||||
//消息体所占长度
|
||||
public short payloadLength = 2;
|
||||
//渠道类型长度
|
||||
public char channelTypeLength = 1;
|
||||
//消息Key用于验证此消息是否合法
|
||||
public short msgKeyLength = 2;
|
||||
//消息key
|
||||
public String msgKey;
|
||||
// 话题ID
|
||||
public String topicID;
|
||||
public short topicIDLength = 2;
|
||||
// //消息是否回执
|
||||
// public int receipt;
|
||||
// //消息加密
|
||||
// public int signal;
|
||||
public WKMsgSetting setting;
|
||||
//消息是否回执长度
|
||||
public short settingLength = 1;
|
||||
private String cryptoPayload;
|
||||
private String msgKey;
|
||||
|
||||
public WKSendMsg() {
|
||||
packetType = WKMsgType.SEND;
|
||||
remainingLength = 8 + 1;
|
||||
cryptoPayload = "";
|
||||
msgKey = "";
|
||||
}
|
||||
|
||||
public String getSendContent() {
|
||||
if (TextUtils.isEmpty(cryptoPayload)) {
|
||||
cryptoPayload = CryptoUtils.getInstance().base64Encode(CryptoUtils.getInstance().aesEncrypt(payload));
|
||||
}
|
||||
return cryptoPayload;
|
||||
}
|
||||
|
||||
public String getMsgKey() {
|
||||
if (TextUtils.isEmpty(msgKey)) {
|
||||
String sendContent = getSendContent();
|
||||
String key = clientSeq + clientMsgNo + channelId + channelType + sendContent;
|
||||
byte[] msgKeyByte = CryptoUtils.getInstance().aesEncrypt(key);
|
||||
msgKey = CryptoUtils.getInstance().digestMD5(CryptoUtils.getInstance().base64Encode(msgKeyByte));
|
||||
}
|
||||
return msgKey;
|
||||
}
|
||||
|
||||
private int getTopicLength() {
|
||||
int topicLen = 0;
|
||||
if (setting.topic == 1) {
|
||||
topicLen = topicID.length();
|
||||
topicLen += topicIDLength;
|
||||
}
|
||||
return topicLen;
|
||||
}
|
||||
|
||||
public int getTotalLength() {
|
||||
int topicLen = getTopicLength();
|
||||
String msgKeyContent = getMsgKey();
|
||||
String sendContent = getSendContent();
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(getRemainingLength());
|
||||
return 1 + remainingBytes.length
|
||||
+ settingLength
|
||||
+ clientSeqLength
|
||||
+ clientMsgNoLength
|
||||
+ clientMsgNo.length()
|
||||
+ channelIdLength
|
||||
+ channelId.length()
|
||||
+ channelTypeLength
|
||||
+ msgKeyLength
|
||||
+ msgKeyContent.length()
|
||||
+ topicLen
|
||||
+ sendContent.getBytes().length;
|
||||
}
|
||||
|
||||
|
||||
public int getRemainingLength() {
|
||||
String sendContent = getSendContent();
|
||||
String msgKeyContent = getMsgKey();
|
||||
int topicLen = getTopicLength();
|
||||
remainingLength = settingLength
|
||||
+ clientSeqLength
|
||||
+ clientMsgNoLength + clientMsgNo.length()
|
||||
+ channelIdLength + channelId.length()
|
||||
+ channelTypeLength
|
||||
+ msgKeyLength + msgKeyContent.length()
|
||||
+ topicLen
|
||||
+ sendContent.getBytes().length;
|
||||
return remainingLength;
|
||||
}
|
||||
}
|
||||
|
@ -162,6 +162,7 @@ public class WKTypeUtils {
|
||||
WKMsgSetting msgSetting = new WKMsgSetting();
|
||||
msgSetting.receipt = getBit(setting, 7);
|
||||
msgSetting.topic = getBit(setting, 3);
|
||||
msgSetting.stream = getBit(setting, 2);
|
||||
return msgSetting;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user