Compatible stream messages

This commit is contained in:
SL 2023-08-29 15:56:59 +08:00
parent fc1958cf13
commit d4be779c72
59 changed files with 825 additions and 812 deletions

View File

@ -1 +1 @@
72f35014c22dcbfefb5ead739964975c
4cec5fa9bfdf46b27bf0f92d5fc1e0c0

View File

@ -1 +1 @@
eb25fc6ecec221cfb5f46d6804366ed0a49417f0
8871f573ae5c19bbc5aa201471550587db204a50

View File

@ -1 +1 @@
21dabdaa369dad1fe075c88136c9520f1009b7d7867b4abdc5471ccf9571059d
b91dd2bb576fa13822fcfb913eb376a75a4c44fb3532bcc32f6ef55dacf1df7d

View File

@ -1 +1 @@
5dcb35c9ef5e3380f55956f83da6bf5c92a3da3edaf69be371466510578a77f29e0efe377fe11c3c5472188b067b2e83683747a3b4408a9fc953eaa1b7cee2be
cdfb6e0fe8c3d76a5da917346f2cf502b6958238fb136dc3badc9b26d9612b249477a2cabac267265dc07cd425b80103c8acf57baaebfd03aa80215c9a67e049

View File

@ -0,0 +1 @@
a811ccc79ea28ce25f32df13d58450d0

View File

@ -0,0 +1 @@
84a98cd67120c6bf427fe06bf1122bf9ad9eb343

View File

@ -0,0 +1 @@
a02b43e21138332b7eb0213a91a1411ee6235ff29ae89cc4d33978a7ef08d4be

View File

@ -0,0 +1 @@
0e160dd8c66ec6f486f66151ae954b2fbdf5b198a9ed969cc4dd48c575db03b23ff8e65ff3fd2c950042fe749d5c68aef27348f70884fcf485cbb5a33bc392ba

View File

@ -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>

View File

@ -0,0 +1 @@
6498b4614db03e1905bf001469cf95fa

View File

@ -0,0 +1 @@
ce43a2b1beb2ca1154356fa7a58990513fbfcaf5

View File

@ -0,0 +1 @@
2256a0f7a1909d270406d96d1bbee652f83f215d3594de4de1e4fc3153f1ba43

View File

@ -0,0 +1 @@
e0ba06d4ca0412ea3db840f193369a48db5fbc60eb0745042a35e96e3ccb8dad3acc3f09bec4dbcef7cee13806ea68d431ac28aceaa316f5168177039accf7b3

View File

@ -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>

View File

@ -1 +1 @@
78bcfc18b1a294860edba2e4b488ed1e
b49f24f693949485c42489310069855c

View File

@ -1 +1 @@
e066d8085f791ea404c493fe8683c96f788643bf
afdc20fb84ea50e9266c2fc71e828a54e4986b03

View File

@ -1 +1 @@
c35b0d1ac9132a9bca006c5263fa4bb120d0f36487e1a97c8bed3f57770c19af
4154fb5d8b1d9905f6b41ee3f017fbf8546309ee40eedb31b159609390163e61

View File

@ -1 +1 @@
d798765fbd3a123f0cb55e233624263f43abe5f8a3dce892e6dd0a26d15967c2a2533d597fa407b72e4f1dc553b58af5bd0785de63f4d56c297b200ced63f5c5
4c8e8bbaa6e68ee2a84da4bf15f5d4aa76419028283f37890c1fa98690d53365746d86c7aa54c76cb6a8c30e60707e6c2a236628bfe7cc887af8262e18da2fa8

View File

@ -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 {

View File

@ -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 { *; }

View File

@ -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() {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,5 +0,0 @@
package com.xinbida.wukongim.interfaces;
public interface ICryptoSignalData {
void getChannelSignalData(String channelID, byte channelTyp, ICryptoSignalDataResult iCryptoSignalDataResult);
}

View File

@ -1,7 +0,0 @@
package com.xinbida.wukongim.interfaces;
import com.xinbida.wukongim.entity.WKSignalKey;
public interface ICryptoSignalDataResult {
void onResult(WKSignalKey signalKey);
}

View File

@ -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);
/**
* 重连
*/

View File

@ -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

View File

@ -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();
}

View File

@ -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() {

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;

View 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;
}
}

View 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);
}
}

View File

@ -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;
}

View 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;
}
}

View File

@ -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;

View File

@ -2,8 +2,6 @@ package com.xinbida.wukongim.msgmodel;
import android.os.Parcel;
import com.xinbida.wukongim.protocol.WKMessageContent;
/**
* 2020-04-04 10:39
* 多媒体消息如果自定义消息带附件需继承该类

View File

@ -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;

View File

@ -1,4 +1,4 @@
package com.xinbida.wukongim.protocol;
package com.xinbida.wukongim.msgmodel;
import android.os.Parcel;
import android.os.Parcelable;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -11,8 +11,6 @@ public class WKConnectAckMsg extends WKBaseMsg {
public long timeDiff;
//连接原因码
public short reasonCode;
//时间戳长度
public long timeDiffLength = 8;
// 服务端公钥
public String serverKey;
// 安全码

View File

@ -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();
}
}

View File

@ -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;//序列号

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}