mirror of
https://github.com/WuKongIM/WuKongIMAndroidSDK
synced 2025-06-02 23:39:05 +00:00
update connect
This commit is contained in:
parent
eb54d0f4d6
commit
b0069699df
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -8,7 +8,7 @@
|
||||
</option>
|
||||
</component>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
@ -3,6 +3,7 @@ package com.xinbida.wukongdemo;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
@ -130,6 +131,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
JSONObject jsonObject = new JSONObject(data);
|
||||
String tcp_addr = jsonObject.optString("tcp_addr");
|
||||
String[] strings = tcp_addr.split(":");
|
||||
Log.e("获取连接的IP","-->"+data);
|
||||
andPortListener.onGetSocketIpAndPort(strings[0], Integer.parseInt(strings[1]));
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
@ -34,6 +34,8 @@ class MessageAdapter extends BaseMultiItemQuickAdapter<UIMessageEntity, BaseView
|
||||
}
|
||||
String name = uiMessageEntity.msg.fromUID.substring(0, 1);
|
||||
nameTv.setText(name);
|
||||
contentTv.setText(uiMessageEntity.msg.baseContentMsgModel.getDisplayContent());
|
||||
if (uiMessageEntity.msg.baseContentMsgModel!=null){
|
||||
contentTv.setText(uiMessageEntity.msg.baseContentMsgModel.getDisplayContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
@ -1 +1 @@
|
||||
270067ab5c7532476f63dd87238a22f5
|
||||
5eab9c1249668bd09cfb8a5718dc9643
|
@ -1 +1 @@
|
||||
0467491103963d99eb9ebc6eb9b53b9e69c0b914
|
||||
b16bea7a6426af069315ace7611d0ed3a2c6aa8f
|
@ -1 +1 @@
|
||||
221fe85ce0f33eaa2e3845512630bb5888070a5f087dfb99acb6d169a9cebd24
|
||||
5cb5fc944333eeffd03bdd716ff17366d0cb489e2aa48a1f9cccfe4062dea75c
|
@ -1 +1 @@
|
||||
bca2b8de1699abf34669d9621d97a9e479d5e850d8821ed786aaecd422c4de5d622d40ae2349ae700ac841b5084b42243e3d2a58f3f2e7ece73031268aab4b1c
|
||||
4325ab87ab3ec56e9b44a5965526825a1e26370e7f5d59bdf7e58f1deefbb9061bc11164af920bcda809e76f2ccaa550d89602ad0e6d1e4a1ebf636f29c1e876
|
@ -8,6 +8,6 @@
|
||||
<versions>
|
||||
<version>1.0.1</version>
|
||||
</versions>
|
||||
<lastUpdated>20230723092612</lastUpdated>
|
||||
<lastUpdated>20230820031318</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
||||
|
@ -1 +1 @@
|
||||
b02d2b70b6fded0280d37f36fcbcb04a
|
||||
c9af3f3712d90a532edf6c36cb9cbaff
|
@ -1 +1 @@
|
||||
8a0f70f3f2c3d90ee9d5cd55bf7c9b69ccdc2d13
|
||||
1b93babf2a04c0b02d01bde8b390c911b159536b
|
@ -1 +1 @@
|
||||
a0d2ef51822269eeb0fe540d7c736dfb16b7edecad096c123570b9fe40321171
|
||||
aa187a0220cd5366a8cee104ece1f2d570ea7c9cce02d24b21941393b6f38ff6
|
@ -1 +1 @@
|
||||
39d724b42413976f8a1680f17a9834bd77a5418cf454ed0440d37d8e24500904384d67c00f9d560c6c6e034489715903828316a05c80e8680abfa8ec24969771
|
||||
6c02439c3b2faaf9b36e4e747ee6216210d72ff0edc436db71d4080fd1ce12e91fd70a68dac0f7eea3aa79ea4c8f75aab2a397fe8ff1c8ca03f986e5566800f2
|
1
wkim/proguard-rules.pro
vendored
1
wkim/proguard-rules.pro
vendored
@ -50,3 +50,4 @@
|
||||
-keep,includedescriptorclasses class net.sqlcipher.** { *; }
|
||||
-keep,includedescriptorclasses interface net.sqlcipher.** { *; }
|
||||
|
||||
-flattenpackagehierarchy 'wkim'
|
@ -12,7 +12,7 @@ import com.xinbida.wukongim.manager.MsgManager;
|
||||
import com.xinbida.wukongim.manager.ReminderManager;
|
||||
import com.xinbida.wukongim.manager.RobotManager;
|
||||
import com.xinbida.wukongim.message.MessageHandler;
|
||||
import com.xinbida.wukongim.utils.Curve25519Utils;
|
||||
import com.xinbida.wukongim.utils.CryptoUtils;
|
||||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
|
||||
/**
|
||||
@ -70,7 +70,7 @@ public class WKIM {
|
||||
WKIMApplication.getInstance().setUid(uid);
|
||||
WKIMApplication.getInstance().setToken(token);
|
||||
// 初始化加密key
|
||||
Curve25519Utils.getInstance().initKey();
|
||||
CryptoUtils.getInstance().initKey();
|
||||
// 初始化默认消息类型
|
||||
getMsgManager().initNormalMsg();
|
||||
// 初始化数据库
|
||||
|
@ -490,6 +490,9 @@ public class ConversationDbManager {
|
||||
extra.browseTo = WKCursor.readLong(cursor, "browse_to");
|
||||
extra.draftUpdatedAt = WKCursor.readLong(cursor, "draft_updated_at");
|
||||
extra.version = WKCursor.readLong(cursor, "version");
|
||||
if (cursor.getColumnIndex("extra_version") > 0) {
|
||||
extra.version = WKCursor.readLong(cursor, "extra_version");
|
||||
}
|
||||
return extra;
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,9 @@ public class MsgDbManager {
|
||||
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
||||
WKMsg wkMsg = serializeMsg(cursor);
|
||||
wkMsg.setChannelInfo(wkChannel);
|
||||
messageIds.add(wkMsg.messageID);
|
||||
if (!TextUtils.isEmpty(wkMsg.messageID)){
|
||||
messageIds.add(wkMsg.messageID);
|
||||
}
|
||||
if (wkMsg.baseContentMsgModel != null && wkMsg.baseContentMsgModel.reply != null && !TextUtils.isEmpty(wkMsg.baseContentMsgModel.reply.message_id)) {
|
||||
replyMsgIds.add(wkMsg.baseContentMsgModel.reply.message_id);
|
||||
}
|
||||
@ -473,7 +475,7 @@ public class MsgDbManager {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public synchronized void insertMsgList1(List<WKMsg> list) {
|
||||
public synchronized void insertMsgList(List<WKMsg> list) {
|
||||
if (list == null || list.size() == 0) return;
|
||||
if (list.size() == 1) {
|
||||
insertMsg(list.get(0));
|
||||
@ -1238,13 +1240,41 @@ public class MsgDbManager {
|
||||
|
||||
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
||||
WKMsg msg = serializeMsg(cursor);
|
||||
boolean isAdd = true;
|
||||
if (msg.channelType == WKChannelType.GROUP) {
|
||||
//查询群成员信息
|
||||
gChannelIds.add(msg.channelID);
|
||||
for (int i = 0; i < gChannelIds.size(); i++) {
|
||||
if (gChannelIds.get(i).equals(msg.fromUID)) {
|
||||
isAdd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isAdd) {
|
||||
gChannelIds.add(msg.fromUID);
|
||||
}
|
||||
} else {
|
||||
pChannelIds.add(msg.channelID);
|
||||
for (int i = 0; i < pChannelIds.size(); i++) {
|
||||
if (pChannelIds.get(i).equals(msg.channelID)) {
|
||||
isAdd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isAdd) {
|
||||
pChannelIds.add(msg.channelID);
|
||||
}
|
||||
|
||||
}
|
||||
fromChannelIds.add(msg.fromUID);
|
||||
isAdd = true;
|
||||
for (int i = 0; i < fromChannelIds.size(); i++) {
|
||||
if (fromChannelIds.get(i).equals(msg.fromUID)) {
|
||||
isAdd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isAdd) {
|
||||
fromChannelIds.add(msg.fromUID);
|
||||
}
|
||||
|
||||
list.add(msg);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* 2020-05-10 19:16
|
||||
* 狸猫频道搜索结果
|
||||
* 频道搜索结果
|
||||
*/
|
||||
public class WKChannelSearchResult implements Parcelable {
|
||||
//频道信息
|
||||
|
@ -5,7 +5,7 @@ import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* 2020-05-10 22:26
|
||||
* 狸猫消息搜索结果
|
||||
* 消息搜索结果
|
||||
*/
|
||||
public class WKMessageSearchResult implements Parcelable {
|
||||
//消息对应的频道信息
|
||||
|
@ -6,13 +6,11 @@ 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.interfaces.IGetSocketIpAndPortListener;
|
||||
import com.xinbida.wukongim.message.ConnectionHandler;
|
||||
import com.xinbida.wukongim.message.MessageHandler;
|
||||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@ -34,7 +32,7 @@ public class ConnectionManager extends BaseManager {
|
||||
|
||||
|
||||
private IGetIpAndPort iGetIpAndPort;
|
||||
private ConcurrentHashMap<String, IConnectionStatus> concurrentHashMap;
|
||||
private ConcurrentHashMap<String, IConnectionStatus> connectionListenerMap;
|
||||
|
||||
// 连接
|
||||
public void connection() {
|
||||
@ -100,9 +98,9 @@ public class ConnectionManager extends BaseManager {
|
||||
}
|
||||
|
||||
public void setConnectionStatus(int status, String reason) {
|
||||
if (concurrentHashMap != null && concurrentHashMap.size() > 0) {
|
||||
if (connectionListenerMap != null && connectionListenerMap.size() > 0) {
|
||||
runOnMainThread(() -> {
|
||||
for (Map.Entry<String, IConnectionStatus> entry : concurrentHashMap.entrySet()) {
|
||||
for (Map.Entry<String, IConnectionStatus> entry : connectionListenerMap.entrySet()) {
|
||||
entry.getValue().onStatus(status, reason);
|
||||
}
|
||||
});
|
||||
@ -112,14 +110,14 @@ public class ConnectionManager extends BaseManager {
|
||||
// 监听连接状态
|
||||
public void addOnConnectionStatusListener(String key, IConnectionStatus iConnectionStatus) {
|
||||
if (iConnectionStatus == null || TextUtils.isEmpty(key)) return;
|
||||
if (concurrentHashMap == null) concurrentHashMap = new ConcurrentHashMap<>();
|
||||
concurrentHashMap.put(key, iConnectionStatus);
|
||||
if (connectionListenerMap == null) connectionListenerMap = new ConcurrentHashMap<>();
|
||||
connectionListenerMap.put(key, iConnectionStatus);
|
||||
}
|
||||
|
||||
// 移除监听
|
||||
public void removeOnConnectionStatusListener(String key) {
|
||||
if (!TextUtils.isEmpty(key) && concurrentHashMap != null) {
|
||||
concurrentHashMap.remove(key);
|
||||
if (!TextUtils.isEmpty(key) && connectionListenerMap != null) {
|
||||
connectionListenerMap.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ public class ConversationManager extends BaseManager {
|
||||
List<WKUIConversationMsg> uiMsgList = new ArrayList<>();
|
||||
if (conversationMsgList.size() > 0 || msgList.size() > 0) {
|
||||
if (msgList.size() > 0) {
|
||||
MsgDbManager.getInstance().insertMsgList1(msgList);
|
||||
MsgDbManager.getInstance().insertMsgList(msgList);
|
||||
}
|
||||
try {
|
||||
if (conversationMsgList.size() > 0) {
|
||||
|
@ -82,7 +82,7 @@ public class MsgManager extends BaseManager {
|
||||
return MsgManagerBinder.msgManager;
|
||||
}
|
||||
|
||||
private final long limOrderSeqFactor = 1000L;
|
||||
private final long wkOrderSeqFactor = 1000L;
|
||||
// 消息修改
|
||||
private ConcurrentHashMap<String, IRefreshMsg> refreshMsgListenerMap;
|
||||
// 监听发送消息回调
|
||||
@ -272,10 +272,10 @@ public class MsgManager extends BaseManager {
|
||||
}
|
||||
|
||||
private long getOrNearbyMsgSeq(long orderSeq) {
|
||||
if (orderSeq % limOrderSeqFactor == 0) {
|
||||
return orderSeq / limOrderSeqFactor;
|
||||
if (orderSeq % wkOrderSeqFactor == 0) {
|
||||
return orderSeq / wkOrderSeqFactor;
|
||||
}
|
||||
return (orderSeq - orderSeq % limOrderSeqFactor) / limOrderSeqFactor;
|
||||
return (orderSeq - orderSeq % wkOrderSeqFactor) / wkOrderSeqFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,8 +307,8 @@ public class MsgManager extends BaseManager {
|
||||
oldestOrderSeq = aroundMsgOrderSeq;
|
||||
} else {
|
||||
if (minOrderSeq + limit < aroundMsgOrderSeq) {
|
||||
if (aroundMsgOrderSeq % limOrderSeqFactor == 0) {
|
||||
oldestOrderSeq = (aroundMsgOrderSeq / limOrderSeqFactor - 3) * limOrderSeqFactor;
|
||||
if (aroundMsgOrderSeq % wkOrderSeqFactor == 0) {
|
||||
oldestOrderSeq = (aroundMsgOrderSeq / wkOrderSeqFactor - 3) * wkOrderSeqFactor;
|
||||
} else
|
||||
oldestOrderSeq = aroundMsgOrderSeq - 3;
|
||||
// oldestOrderSeq = aroundMsgOrderSeq;
|
||||
@ -468,18 +468,18 @@ public class MsgManager extends BaseManager {
|
||||
long tempOrderSeq = MsgDbManager.getInstance().getMaxOrderSeq(channelID, channelType);
|
||||
return tempOrderSeq + 1;
|
||||
}
|
||||
return messageSeq * limOrderSeqFactor;
|
||||
return messageSeq * wkOrderSeqFactor;
|
||||
}
|
||||
|
||||
public long getMessageSeq(long messageOrderSeq) {
|
||||
if (messageOrderSeq % limOrderSeqFactor == 0) {
|
||||
return messageOrderSeq / limOrderSeqFactor;
|
||||
if (messageOrderSeq % wkOrderSeqFactor == 0) {
|
||||
return messageOrderSeq / wkOrderSeqFactor;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getReliableMessageSeq(long messageOrderSeq) {
|
||||
return messageOrderSeq / limOrderSeqFactor;
|
||||
return messageOrderSeq / wkOrderSeqFactor;
|
||||
}
|
||||
|
||||
public long getMaxSeqWithChannel(String channelID, byte channelType) {
|
||||
@ -910,7 +910,7 @@ public class MsgManager extends BaseManager {
|
||||
MsgDbManager.getInstance().saveOrUpdateMsgExtras(msgExtraList);
|
||||
}
|
||||
if (msgList.size() > 0) {
|
||||
MsgDbManager.getInstance().insertMsgList1(msgList);
|
||||
MsgDbManager.getInstance().insertMsgList(msgList);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1038,7 +1038,7 @@ public class MsgManager extends BaseManager {
|
||||
msg.clientMsgNO = wkSyncRecent.client_msg_no;
|
||||
msg.fromUID = wkSyncRecent.from_uid;
|
||||
msg.timestamp = wkSyncRecent.timestamp;
|
||||
msg.orderSeq = msg.messageSeq * limOrderSeqFactor;
|
||||
msg.orderSeq = msg.messageSeq * wkOrderSeqFactor;
|
||||
msg.voiceStatus = wkSyncRecent.voice_status;
|
||||
msg.isDeleted = wkSyncRecent.is_deleted;
|
||||
msg.status = WKSendMsgResult.send_success;
|
||||
|
@ -110,7 +110,9 @@ class ClientHandler implements IDataHandler, IConnectHandler,
|
||||
}
|
||||
}
|
||||
byte[] buffBytes = iNonBlockingConnection.readBytesByLength(readLen);
|
||||
ConnectionHandler.getInstance().receivedData(buffBytes.length, buffBytes);
|
||||
if (buffBytes.length > 0) {
|
||||
ConnectionHandler.getInstance().receivedData(buffBytes);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
@ -123,9 +125,20 @@ class ClientHandler implements IDataHandler, IConnectHandler,
|
||||
@Override
|
||||
public boolean onDisconnect(INonBlockingConnection iNonBlockingConnection) {
|
||||
WKLoggerUtils.getInstance().e("连接断开");
|
||||
if (iNonBlockingConnection != null && !TextUtils.isEmpty(iNonBlockingConnection.getId()) && iNonBlockingConnection.getAttachment() != null) {
|
||||
String id = iNonBlockingConnection.getId();
|
||||
Object attachmentObject = iNonBlockingConnection.getAttachment();
|
||||
if (attachmentObject instanceof String) {
|
||||
String att = (String) attachmentObject;
|
||||
String attStr = "close" + id;
|
||||
if (att.equals(attStr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (WKIMApplication.getInstance().isCanConnect) {
|
||||
ConnectionHandler.getInstance().forcedReconnection();
|
||||
}else {
|
||||
} else {
|
||||
WKLoggerUtils.getInstance().e("不能重连-->");
|
||||
}
|
||||
close(iNonBlockingConnection);
|
||||
|
@ -81,6 +81,10 @@ public class ConnectionHandler {
|
||||
private final long requestIPTimeoutTime = 6;
|
||||
public String socketSingleID;
|
||||
private String lastRequestId;
|
||||
private final long reconnectDelay = 1500;
|
||||
public volatile Handler reconnectionHandler = new Handler(Objects.requireNonNull(Looper.myLooper()));
|
||||
|
||||
Runnable reconnectionRunnable = this::reconnection;
|
||||
|
||||
public synchronized void forcedReconnection() {
|
||||
isReConnecting = false;
|
||||
@ -99,6 +103,7 @@ public class ConnectionHandler {
|
||||
return;
|
||||
}
|
||||
connectStatus = WKConnectStatus.fail;
|
||||
reconnectionHandler.removeCallbacks(reconnectionRunnable);
|
||||
boolean isHaveNetwork = WKIMApplication.getInstance().isNetworkConnected();
|
||||
if (isHaveNetwork) {
|
||||
closeConnect();
|
||||
@ -109,18 +114,7 @@ public class ConnectionHandler {
|
||||
if (!ConnectionTimerHandler.getInstance().checkNetWorkTimerIsRunning) {
|
||||
WKIM.getInstance().getConnectionManager().setConnectionStatus(WKConnectStatus.noNetwork, WKConnectReason.NoNetwork);
|
||||
isReConnecting = false;
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
super.run();
|
||||
try {
|
||||
Thread.sleep(1500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
new Handler(Looper.getMainLooper()).post(() -> reconnection());
|
||||
}
|
||||
}.start();
|
||||
reconnectionHandler.postDelayed(reconnectionRunnable, reconnectDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -128,7 +122,7 @@ public class ConnectionHandler {
|
||||
private synchronized void getIPAndPort() {
|
||||
if (!WKIMApplication.getInstance().isNetworkConnected()) {
|
||||
isReConnecting = false;
|
||||
reconnection();
|
||||
reconnectionHandler.postDelayed(reconnectionRunnable, reconnectDelay);
|
||||
return;
|
||||
}
|
||||
if (!WKIMApplication.getInstance().isCanConnect) {
|
||||
@ -144,7 +138,7 @@ public class ConnectionHandler {
|
||||
if (TextUtils.isEmpty(ip) || port == 0) {
|
||||
WKLoggerUtils.getInstance().e("返回连接IP或port错误," + String.format("ip:%s & port:%s", ip, port));
|
||||
isReConnecting = false;
|
||||
reconnection();
|
||||
reconnectionHandler.postDelayed(reconnectionRunnable, reconnectDelay);
|
||||
} else {
|
||||
if (lastRequestId.equals(requestId)) {
|
||||
ConnectionHandler.this.ip = ip;
|
||||
@ -156,7 +150,7 @@ public class ConnectionHandler {
|
||||
} else {
|
||||
if (connectionIsNull()) {
|
||||
WKLoggerUtils.getInstance().e("请求IP的编号不一致,重连中");
|
||||
reconnection();
|
||||
reconnectionHandler.postDelayed(reconnectionRunnable, reconnectDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,8 +184,8 @@ public class ConnectionHandler {
|
||||
sendMessage(new WKConnectMsg());
|
||||
}
|
||||
|
||||
void receivedData(int length, byte[] data) {
|
||||
MessageHandler.getInstance().cutBytes(length, data,
|
||||
void receivedData(byte[] data) {
|
||||
MessageHandler.getInstance().cutBytes( data,
|
||||
new IReceivedMsgListener() {
|
||||
|
||||
public void sendAckMsg(
|
||||
@ -524,8 +518,9 @@ public class ConnectionHandler {
|
||||
private void closeConnect() {
|
||||
if (connection != null && connection.isOpen()) {
|
||||
try {
|
||||
WKLoggerUtils.getInstance().e("stop connection" + connection.getId());
|
||||
WKLoggerUtils.getInstance().e("stop connection:" + connection.getId());
|
||||
// connection.flush();
|
||||
connection.setAttachment("close" + connection.getId());
|
||||
connection.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -25,9 +25,8 @@ 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.AESEncryptUtils;
|
||||
import com.xinbida.wukongim.utils.BigTypeUtils;
|
||||
import com.xinbida.wukongim.utils.Curve25519Utils;
|
||||
import com.xinbida.wukongim.utils.CryptoUtils;
|
||||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||||
|
||||
@ -42,6 +41,7 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 5/21/21 11:28 AM
|
||||
@ -70,7 +70,7 @@ class MessageConvertHandler {
|
||||
+ WKIMApplication.getInstance().getToken().length()
|
||||
+ connectMsg.clientTimeStampLength
|
||||
+ connectMsg.clientKeyLength
|
||||
+ Curve25519Utils.getInstance().getPublicKey().length();
|
||||
+ CryptoUtils.getInstance().getPublicKey().length();
|
||||
|
||||
byte[] remainingBytes = WKTypeUtils.getInstance().getRemainingLengthByte(remainingLength);
|
||||
int totalLen = 1 + remainingBytes.length
|
||||
@ -84,7 +84,7 @@ class MessageConvertHandler {
|
||||
+ WKIMApplication.getInstance().getToken().length()
|
||||
+ connectMsg.clientTimeStampLength
|
||||
+ connectMsg.clientKeyLength
|
||||
+ Curve25519Utils.getInstance().getPublicKey().length();
|
||||
+ CryptoUtils.getInstance().getPublicKey().length();
|
||||
|
||||
byte[] bytes = new byte[totalLen];
|
||||
ByteBuffer buffer = ByteBuffer.allocate(totalLen).order(
|
||||
@ -102,8 +102,8 @@ class MessageConvertHandler {
|
||||
buffer.putShort((short) WKIMApplication.getInstance().getToken().length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(WKIMApplication.getInstance().getToken()));
|
||||
buffer.putLong(connectMsg.clientTimestamp);
|
||||
buffer.putShort((short) Curve25519Utils.getInstance().getPublicKey().length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(Curve25519Utils.getInstance().getPublicKey()));
|
||||
buffer.putShort((short) CryptoUtils.getInstance().getPublicKey().length());
|
||||
buffer.put(WKTypeUtils.getInstance().stringToByte(CryptoUtils.getInstance().getPublicKey()));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -144,16 +144,16 @@ class MessageConvertHandler {
|
||||
|
||||
byte[] enSendMsg(WKSendMsg sendMsg) {
|
||||
// 先加密内容
|
||||
byte[] contentByte = AESEncryptUtils.aesEncrypt(sendMsg.payload, Curve25519Utils.getInstance().aesKey, Curve25519Utils.getInstance().salt);
|
||||
String sendContent = AESEncryptUtils.base64Encode(contentByte);
|
||||
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 = AESEncryptUtils.aesEncrypt(msgKey, Curve25519Utils.getInstance().aesKey, Curve25519Utils.getInstance().salt);
|
||||
String msgKeyContent = AESEncryptUtils.base64Encode(msgKeyByte);
|
||||
msgKeyContent = AESEncryptUtils.digest(msgKeyContent);
|
||||
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) {
|
||||
@ -269,7 +269,7 @@ class MessageConvertHandler {
|
||||
connectAckMsg.serverKey = serverKey;
|
||||
connectAckMsg.salt = salt;
|
||||
//保存公钥和安全码
|
||||
Curve25519Utils.getInstance().setServerKeyAndSalt(connectAckMsg.serverKey, connectAckMsg.salt);
|
||||
CryptoUtils.getInstance().setServerKeyAndSalt(connectAckMsg.serverKey, connectAckMsg.salt);
|
||||
|
||||
connectAckMsg.timeDiff = time;
|
||||
connectAckMsg.remainingLength = remainingLength;
|
||||
@ -428,7 +428,7 @@ class MessageConvertHandler {
|
||||
if (read == -1) return receivedMsg;
|
||||
|
||||
String content = WKTypeUtils.getInstance().bytesToString(payload);
|
||||
receivedMsg.payload = AESEncryptUtils.aesDecrypt(AESEncryptUtils.base64Decode(content), Curve25519Utils.getInstance().aesKey, Curve25519Utils.getInstance().salt);
|
||||
receivedMsg.payload = CryptoUtils.getInstance().aesDecrypt(CryptoUtils.getInstance().base64Decode(content));
|
||||
String msgKey = receivedMsg.messageID
|
||||
+ receivedMsg.messageSeq
|
||||
+ receivedMsg.clientMsgNo
|
||||
@ -437,9 +437,9 @@ class MessageConvertHandler {
|
||||
+ receivedMsg.channelID
|
||||
+ receivedMsg.channelType
|
||||
+ content;
|
||||
byte[] result = AESEncryptUtils.aesEncrypt(msgKey, Curve25519Utils.getInstance().aesKey, Curve25519Utils.getInstance().salt);
|
||||
String base64Result = AESEncryptUtils.base64Encode(result);
|
||||
String localMsgKey = AESEncryptUtils.digest(base64Result);
|
||||
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;
|
||||
}
|
||||
|
@ -120,11 +120,9 @@ public class MessageHandler {
|
||||
private List<WKSyncMsg> receivedMsgList;
|
||||
private byte[] cacheData = null;
|
||||
|
||||
synchronized void cutBytes(int available_len, byte[] available_bytes,
|
||||
synchronized void cutBytes(byte[] available_bytes,
|
||||
IReceivedMsgListener mIReceivedMsgListener) {
|
||||
if (available_len == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cacheData == null || cacheData.length == 0) cacheData = available_bytes;
|
||||
else {
|
||||
//如果上次还存在未解析完的消息将新数据追加到缓存数据中
|
||||
@ -160,7 +158,6 @@ public class MessageHandler {
|
||||
WKLoggerUtils.getInstance().e("pong...");
|
||||
byte[] bytes = Arrays.copyOfRange(lastMsgBytes, 1, lastMsgBytes.length);
|
||||
cacheData = lastMsgBytes = bytes;
|
||||
|
||||
} else {
|
||||
if (packetType < 10) {
|
||||
// TODO: 2019-12-21 计算剩余长度
|
||||
@ -202,7 +199,7 @@ public class MessageHandler {
|
||||
|
||||
private void acceptMsg(byte[] bytes, int no_persist, int sync_once, int red_dot,
|
||||
IReceivedMsgListener mIReceivedMsgListener) {
|
||||
// 字节数组转成消息数组
|
||||
|
||||
if (bytes != null && bytes.length > 0) {
|
||||
WKBaseMsg g_msg;
|
||||
g_msg = MessageConvertHandler.getInstance().decodeMessage(bytes);
|
||||
@ -319,7 +316,7 @@ public class MessageHandler {
|
||||
}
|
||||
allList.add(mMsg.wkMsg);
|
||||
}
|
||||
MsgDbManager.getInstance().insertMsgList1(saveMsgList);
|
||||
MsgDbManager.getInstance().insertMsgList(saveMsgList);
|
||||
//将消息push给UI
|
||||
WKIM.getInstance().getMsgManager().pushNewMsg(allList);
|
||||
groupMsg(list);
|
||||
|
@ -1,10 +1,14 @@
|
||||
package com.xinbida.wukongim.utils;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import com.xinbida.wukongim.WKIMApplication;
|
||||
|
||||
import org.whispersystems.curve25519.Curve25519;
|
||||
import org.whispersystems.curve25519.Curve25519KeyPair;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
@ -17,6 +21,7 @@ import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
@ -25,57 +30,79 @@ import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
|
||||
/**
|
||||
* 2/26/21 12:11 PM
|
||||
* 2/25/21 6:20 PM
|
||||
* 消息加密处理
|
||||
*/
|
||||
public class AESEncryptUtils {
|
||||
|
||||
/**
|
||||
* 加密算法
|
||||
*/
|
||||
private static final String KEY_ALGORITHM = "AES";
|
||||
|
||||
/**
|
||||
* AES 的 密钥长度,32 字节,范围:16 - 32 字节
|
||||
*/
|
||||
public static final int SECRET_KEY_LENGTH = 32;
|
||||
|
||||
/**
|
||||
* 字符编码
|
||||
*/
|
||||
public class CryptoUtils {
|
||||
private byte[] privateKey, publicKey;
|
||||
private byte[] serverKey;
|
||||
private String aesKey;
|
||||
private String salt;
|
||||
private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;
|
||||
|
||||
/**
|
||||
* 秘钥长度不足 16 个字节时,默认填充位数
|
||||
*/
|
||||
private static final String DEFAULT_VALUE = "0";
|
||||
/**
|
||||
* 加解密算法/工作模式/填充方式
|
||||
*/
|
||||
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
|
||||
|
||||
private CryptoUtils() {
|
||||
}
|
||||
|
||||
private static class CryptoUtilsBinder {
|
||||
private final static CryptoUtils util = new CryptoUtils();
|
||||
}
|
||||
|
||||
public static CryptoUtils getInstance() {
|
||||
return CryptoUtilsBinder.util;
|
||||
}
|
||||
|
||||
public void initKey() {
|
||||
Curve25519KeyPair keyPair = Curve25519.getInstance(Curve25519.BEST).generateKeyPair();
|
||||
privateKey = keyPair.getPrivateKey();
|
||||
publicKey = keyPair.getPublicKey();
|
||||
}
|
||||
|
||||
public String getPublicKey() {
|
||||
return Base64.encodeToString(publicKey, Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* aes加密
|
||||
* 设置服务端公钥和安全码
|
||||
*
|
||||
* @param sSrc 内容
|
||||
* @param sKey key
|
||||
* @param salt 安全码
|
||||
* @return
|
||||
* @throws Exception
|
||||
* @param serverKey 公钥
|
||||
* @param salt 安全码
|
||||
*/
|
||||
public static byte[] aesEncrypt(String sSrc, String sKey, String salt) {
|
||||
public void setServerKeyAndSalt(String serverKey, String salt) {
|
||||
|
||||
if (TextUtils.isEmpty(serverKey) || TextUtils.isEmpty(salt)) {
|
||||
this.serverKey = new byte[0];
|
||||
this.salt = "";
|
||||
return;
|
||||
}
|
||||
this.serverKey = base64Decode(serverKey);
|
||||
this.salt = salt;
|
||||
|
||||
Curve25519 cipher = Curve25519.getInstance(Curve25519.BEST);
|
||||
byte[] sharedSecret = cipher.calculateAgreement(this.serverKey, privateKey);
|
||||
String key = digestMD5(base64Encode(sharedSecret));
|
||||
if (!TextUtils.isEmpty(key) && key.length() > 16) {
|
||||
aesKey = key.substring(0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] aesEncrypt(String sSrc) {
|
||||
|
||||
Cipher cipher = null;
|
||||
byte[] encrypted = null;
|
||||
try {
|
||||
cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
||||
byte[] raw = sKey.getBytes(CHARSET_UTF8);
|
||||
byte[] raw = aesKey.getBytes(CHARSET_UTF8);
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
|
||||
//使用CBC模式,需要一个向量iv,可增加加密算法的强度
|
||||
IvParameterSpec iv = new IvParameterSpec(salt.getBytes(CHARSET_UTF8));
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
|
||||
encrypted = cipher.doFinal(sSrc.getBytes());
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
|
||||
InvalidAlgorithmParameterException | IllegalBlockSizeException |
|
||||
BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
Log.e("加密错误:", "-->");
|
||||
}
|
||||
@ -90,12 +117,10 @@ public class AESEncryptUtils {
|
||||
* 解密
|
||||
*
|
||||
* @param sSrc 内容
|
||||
* @param sKey 密钥
|
||||
* @param salt 安全码
|
||||
* @return 内容
|
||||
*/
|
||||
public static String aesDecrypt(byte[] sSrc, String sKey, String salt) {
|
||||
byte[] raw = sKey.getBytes(CHARSET_UTF8);
|
||||
public String aesDecrypt(byte[] sSrc) {
|
||||
byte[] raw = aesKey.getBytes(CHARSET_UTF8);
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
|
||||
Cipher cipher;
|
||||
String content = "";
|
||||
@ -114,21 +139,18 @@ public class AESEncryptUtils {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Base64 字符串 解码成 字节数组
|
||||
*/
|
||||
public static byte[] base64Decode(String data) {
|
||||
public byte[] base64Decode(String data) {
|
||||
return Base64.decode(data, Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 字节数组 转换成 Base64 编码
|
||||
*/
|
||||
public static String base64Encode(byte[] data) {
|
||||
public String base64Encode(byte[] data) {
|
||||
return Base64.encodeToString(data, Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
public static String digest(String password) {
|
||||
public String digestMD5(String password) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
byte[] bytes = digest.digest(password.getBytes());
|
||||
@ -148,9 +170,8 @@ public class AESEncryptUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkRSASign(String content, String sign) {
|
||||
public boolean checkRSASign(String content, String sign) {
|
||||
try {
|
||||
|
||||
String publicKey = WKIMApplication.getInstance().getRSAPublicKey();
|
||||
byte[] keyByte = base64Decode(publicKey);
|
||||
String key = new String(keyByte);
|
||||
@ -165,9 +186,10 @@ public class AESEncryptUtils {
|
||||
boolean result = signature.verify(base64Decode(sign));
|
||||
Log.e("校验结果", result + "");
|
||||
return result;
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | InvalidKeySpecException e) {
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException |
|
||||
InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
Log.e("校验异常", e.getLocalizedMessage());
|
||||
Log.e("校验异常", Objects.requireNonNull(e.getLocalizedMessage()));
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package com.xinbida.wukongim.utils;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
|
||||
import org.whispersystems.curve25519.Curve25519;
|
||||
import org.whispersystems.curve25519.Curve25519KeyPair;
|
||||
|
||||
|
||||
/**
|
||||
* 2/25/21 6:20 PM
|
||||
* 消息加密处理
|
||||
*/
|
||||
public class Curve25519Utils {
|
||||
private byte[] privateKey, publicKey;
|
||||
private byte[] serverKey;
|
||||
public String aesKey;
|
||||
public String salt;
|
||||
|
||||
private Curve25519Utils() {
|
||||
}
|
||||
|
||||
private static class Curve25519UtilsBinder {
|
||||
private final static Curve25519Utils util = new Curve25519Utils();
|
||||
}
|
||||
|
||||
public static Curve25519Utils getInstance() {
|
||||
return Curve25519UtilsBinder.util;
|
||||
}
|
||||
|
||||
public void initKey() {
|
||||
Curve25519KeyPair keyPair = Curve25519.getInstance(Curve25519.BEST).generateKeyPair();
|
||||
privateKey = keyPair.getPrivateKey();
|
||||
publicKey = keyPair.getPublicKey();
|
||||
}
|
||||
|
||||
public String getPublicKey() {
|
||||
return Base64.encodeToString(publicKey, Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置服务端公钥和安全码
|
||||
*
|
||||
* @param serverKey 公钥
|
||||
* @param salt 安全码
|
||||
*/
|
||||
public void setServerKeyAndSalt(String serverKey, String salt) {
|
||||
if (TextUtils.isEmpty(serverKey) || TextUtils.isEmpty(salt)) {
|
||||
this.serverKey = new byte[0];
|
||||
this.salt = "";
|
||||
return;
|
||||
}
|
||||
this.serverKey = AESEncryptUtils.base64Decode(serverKey);
|
||||
this.salt = salt;
|
||||
|
||||
Curve25519 cipher = Curve25519.getInstance(Curve25519.BEST);
|
||||
byte[] sharedSecret = cipher.calculateAgreement(this.serverKey, privateKey);
|
||||
String key = AESEncryptUtils.digest(AESEncryptUtils.base64Encode(sharedSecret));
|
||||
if (!TextUtils.isEmpty(key) && key.length() > 16) {
|
||||
aesKey = key.substring(0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
public String encode(String content) {
|
||||
return content;
|
||||
}
|
||||
|
||||
public String decode(String content) {
|
||||
return content;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user