Compare commits

...
8 Commits
Author SHA1 Message Date
heavyrain2012 b284d10d0f version to 0.71 2021-09-24 21:20:40 +08:00
heavyrain2012 4fd87eb605 add run time in version info 2021-09-20 21:01:40 +08:00
heavyrain2012 f39fd3abd5 version info add run time 2021-09-20 20:44:04 +08:00
heavyrain2012 db25a6ae04 解决只有pushdata没有pushcontent的推送问题 2021-09-20 08:42:47 +08:00
heavyrain2012 edbed585ce 撤回消息推送 2021-09-20 08:21:16 +08:00
heavyrain2012 9ca69d7318 添加voip免打扰开关 2021-09-20 08:12:26 +08:00
heavyrain2012 eeaa9eefdf 添加开关
1,是否不转发管理员消息
2,客户端是否支持kickoff事件
2021-09-07 22:07:54 +08:00
heavyrain2012 92c9d761ed add kicked off error code 2021-09-07 08:29:29 +08:00
20 changed files with 154 additions and 23 deletions
+9
View File
@@ -100,6 +100,11 @@ message.group_mute_exception_types 401,402,403,404,405,407,408,410,411
## 用户被全局禁言时允许发送的消息类型
message.global_mute_exception_types 401,402,403,404,405,407,408,410,411
## 消息转发功能开启时,开关是否不转发server api接口消息。
## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。
message.no_forward_admin_message false
##禁止搜索用户
friend.disable_search false
@@ -215,6 +220,10 @@ server.multi_platform_notification true
# 如果这里改为false,客户端那边需要同步修改pc在线默认通知状态,方法是client的setDefaultSilentWhenPcOnline函数。
server.mobile_default_silent_when_pc_online true
## 客户端是否支持kickoff事件。当客户端被其他端登录踢出时,如果此开关为false时,客户端协议栈上报secret_mismatch。如果此开关为ture时,客户端协议栈上报kicked_off。
## 客户端被踢时上报kicked_off是在2021.9.15之后才加上的。如果客户端协议栈全部为此日期之后的版本才可以打开此开关。
server.client_support_kickoff_event false
#*********************************************************************
# Push server configuration
#*********************************************************************
+1 -1
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.70</version>
<version>0.71</version>
</parent>
<artifactId>moquette-broker</artifactId>
@@ -32,6 +32,7 @@ public class PushMessage {
public String voipDeviceToken;
public boolean isHiddenDetail;
public String language;
public long messageId;
public PushMessage(String sender, int conversationType, String target, int line, int messageContentType, long serverTime, String senderName, String targetName, int unReceivedMsg, int mentionedType, boolean isHiddenDetail, String language) {
this.sender = sender;
@@ -49,6 +50,10 @@ public class PushMessage {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE;
} else if(cntType == 401) {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_ANSWER;
} else if(cntType == 80) {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_RECALLED;
} else if(cntType == 81) {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_DELETED;
} else {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_NORMAL;
}
@@ -35,6 +35,8 @@ public class PushServer {
int PUSH_MESSAGE_TYPE_VOIP_BYE = 2;
int PUSH_MESSAGE_TYPE_FRIEND_REQUEST = 3;
int PUSH_MESSAGE_TYPE_VOIP_ANSWER = 4;
int PUSH_MESSAGE_TYPE_RECALLED = 5;
int PUSH_MESSAGE_TYPE_DELETED = 6;
}
private static PushServer INSTANCE = new PushServer();
@@ -132,6 +132,7 @@ public final class BrokerConstants {
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification";
public static final String SERVER_MOBILE_DEFAULT_SILENT_WHEN_PC_ONLINE = "server.mobile_default_silent_when_pc_online";
public static final String SERVER_CLIENT_SUPPORT_KICKOFF_EVENT = "server.client_support_kickoff_event";
public static final String MESSAGE_ROAMING = "message.roaming";
public static final String MESSAGE_Remote_History_Message = "message.remote_history_message";
@@ -142,6 +143,8 @@ public final class BrokerConstants {
public static final String MESSAGE_Blacklist_Strategy = "message.blacklist.strategy";
public static final String MESSAGE_NO_Forward_Admin_Message = "message.no_forward_admin_message";
public static final String FRIEND_Disable_Search = "friend.disable_search";
public static final String FRIEND_Disable_NickName_Search = "friend.disable_nick_name_search";
public static final String FRIEND_Disable_Friend_Request = "friend.disable_friend_request";
@@ -34,6 +34,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
private String mForwardUrl = null;
private Set<Integer> mForwardMessageTypes = new HashSet<>();
private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。
private boolean mNoForwardAdminMessage = false;
private String mRemoteSensitiveServerUrl = null;
private Set<Integer> mRemoteSensitiveMessageTypes;
@@ -86,6 +87,13 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
Utility.printExecption(LOG, e);
}
try {
mNoForwardAdminMessage = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.MESSAGE_NO_Forward_Admin_Message, "false"));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
@Override
@@ -161,7 +169,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
}
message = message.toBuilder().setFromUser(fromUser).setMessageId(messageId).setServerTimestamp(timestamp).build();
if (mForwardUrl != null && (mForwardMessageTypes.isEmpty() || mForwardMessageTypes.contains(message.getContent().getType()))) {
if (mForwardUrl != null && (mForwardMessageTypes.isEmpty() || mForwardMessageTypes.contains(message.getContent().getType())) && !(isAdmin && mNoForwardAdminMessage)) {
publisher.forwardMessage(message, mForwardUrl);
}
@@ -121,6 +121,7 @@ public class MemoryMessagesStore implements IMessagesStore {
private volatile long lastUpdateSensitiveTime = 0;
private ConcurrentHashMap<String, Boolean> userGlobalSlientMap = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Boolean> userVoipSlientMap = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Boolean> userPushHiddenDetail = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Boolean> userConvSlientMap = new ConcurrentHashMap<>();
@@ -2041,7 +2042,20 @@ public class MemoryMessagesStore implements IMessagesStore {
String recalledContent = json.toJSONString();
message = message.toBuilder().setContent(WFCMessage.MessageContent.newBuilder().setContent(operatorId).setType(80).setData(ByteString.copyFrom(String.valueOf(messageUid).getBytes())).setExtra(recalledContent)).build();
JSONObject pushData = new JSONObject();
pushData.put("messageUid", messageUid);
message = message.toBuilder().setContent(WFCMessage.MessageContent.newBuilder()
.setContent(operatorId)
.clearSearchableContent()
.clearPushContent()
.setPersistFlag(1)
.setExpireDuration(0)
.setMentionedType(0)
.setType(80)
.setData(ByteString.copyFrom(String.valueOf(messageUid).getBytes()))
.setPushData(pushData.toJSONString())
.setExtra(recalledContent)).build();
messageBundle.setMessage(message);
messageBundle.setFromClientId(clientId);
@@ -3378,6 +3392,8 @@ public class MemoryMessagesStore implements IMessagesStore {
userConvSlientMap.remove(key);
} else if(request.getScope() == UserSettingScope.kUserSettingGlobalSilent) {
userGlobalSlientMap.remove(userId);
} else if(request.getScope() == UserSettingScope.kUserSettingVoipSilent) {
userVoipSlientMap.remove(userId);
} else if(request.getScope() == UserSettingScope.kUserSettingHiddenNotificationDetail) {
userPushHiddenDetail.remove(userId);
}
@@ -3408,6 +3424,21 @@ public class MemoryMessagesStore implements IMessagesStore {
return slient;
}
@Override
public boolean getUserVoipSilent(String userId) {
Boolean slient = userVoipSlientMap.get(userId);
if (slient == null) {
WFCMessage.UserSettingEntry entry = getUserSetting(userId, UserSettingScope.kUserSettingVoipSilent, null);
if (entry == null || !entry.getValue().equals("1")) {
slient = false;
} else {
slient = true;
}
userVoipSlientMap.put(userId, slient);
}
return slient;
}
@Override
public boolean getUserPushHiddenDetail(String userId) {
Boolean hidden = userPushHiddenDetail.get(userId);
@@ -39,6 +39,7 @@ public class MemorySessionStore implements ISessionsStore {
private static final Logger LOG = LoggerFactory.getLogger(MemorySessionStore.class);
private boolean supportMultiEndpoint = false;
private boolean clientSupportKickoff = false;
public static class Session implements Comparable<Session>{
final String clientID;
@@ -280,7 +281,14 @@ public class MemorySessionStore implements ISessionsStore {
this.databaseStore = databaseStore;
try {
supportMultiEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_ENDPOINT));
supportMultiEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_ENDPOINT, "false"));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
clientSupportKickoff = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_CLIENT_SUPPORT_KICKOFF_EVENT, "false"));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
@@ -456,20 +464,32 @@ public class MemorySessionStore implements ISessionsStore {
if (session != null && session.getDeleted() == 0) {
LOG.error("already exists a session for client <{}>, bad condition", clientID);
throw new IllegalArgumentException("Can't create a session with the ID of an already existing" + clientID);
return ErrorCode.ERROR_CODE_SUCCESS;
}
if (session != null && session.getDeleted() > 0) {
return ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH;
if(clientSupportKickoff) {
return ErrorCode.ERROR_CODE_KICKED_OFF;
} else {
return ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH;
}
}
ClientSession clientSession = new ClientSession(clientID, this);
session = databaseStore.getSession(username, clientID, clientSession);
if (session == null || session.getDeleted() > 0) {
if (session == null) {
return ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH;
}
if(session.getDeleted() > 0) {
if(clientSupportKickoff) {
return ErrorCode.ERROR_CODE_KICKED_OFF;
} else {
return ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH;
}
}
sessions.put(clientID, session);
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
sessionSet.add(clientID);
@@ -80,6 +80,7 @@ public class Server {
}
private ServerAcceptor m_acceptor;
private long startTime;
private boolean m_shutdowning = false;
@@ -102,6 +103,10 @@ public class Server {
System.out.println(BANNER);
}
public Server() {
startTime = System.currentTimeMillis();
}
public static void start(String[] args) throws IOException {
instance = new Server();
final IConfig config = defaultConfig();
@@ -513,4 +518,7 @@ public class Server {
public ThreadPoolExecutorWrapper getCallbackScheduler() {
return callbackScheduler;
}
public long getRunTime() {
return (System.currentTimeMillis() - startTime)/1000;
}
}
@@ -195,6 +195,7 @@ public interface IMessagesStore {
long updateUserSettings(String userId, WFCMessage.ModifyUserSettingReq request, String clientId);
void clearUserSettings(String userId);
boolean getUserGlobalSilent(String userId);
boolean getUserVoipSilent(String userId);
boolean getUserPushHiddenDetail(String userId);
boolean getUserConversationSilent(String userId, WFCMessage.Conversation conversation);
@@ -160,9 +160,9 @@ public class MessagesPublisher {
}
}
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageHead, Collection<String> receivers, String pushContent, String pushData, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag) {
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageId, Collection<String> receivers, String pushContent, String pushData, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag) {
if (persistFlag == Transparent) {
publishTransparentMessage2Receivers(messageHead, receivers, pullType, exceptClientId);
publishTransparentMessage2Receivers(messageId, receivers, pullType, exceptClientId);
return;
}
@@ -174,7 +174,7 @@ public class MessagesPublisher {
WFCMessage.Robot robot = m_messagesStore.getRobot(user);
if (robot != null && !StringUtil.isNullOrEmpty(robot.getCallback())) {
if (message == null) {
message = m_messagesStore.getMessage(messageHead);
message = m_messagesStore.getMessage(messageId);
}
final WFCMessage.Message finalMsg = message;
Server.getServer().getCallbackScheduler().execute(() -> {
@@ -191,9 +191,9 @@ public class MessagesPublisher {
}
long messageSeq;
if (pullType != ProtoConstants.PullType.Pull_ChatRoom) {
messageSeq = m_messagesStore.insertUserMessages(sender, conversationType, target, line, messageContentType, user, messageHead);
messageSeq = m_messagesStore.insertUserMessages(sender, conversationType, target, line, messageContentType, user, messageId);
} else {
messageSeq = m_messagesStore.insertChatroomMessages(user, line, messageHead);
messageSeq = m_messagesStore.insertChatroomMessages(user, line, messageId);
}
Collection<Session> sessions = m_sessionsStore.sessionForUser(user);
@@ -253,12 +253,18 @@ public class MessagesPublisher {
}
boolean isSilent;
boolean isVoipSilent;
boolean isNoDisturb;
boolean isConvSilent = false;
if (pullType == ProtoConstants.PullType.Pull_ChatRoom) {
isSilent = true;
isConvSilent = true;
isVoipSilent = true;
isNoDisturb = true;
} else {
isSilent = false;
isVoipSilent = false;
isNoDisturb = false;
if (!user.equals(sender)) {
WFCMessage.Conversation conversation;
@@ -278,14 +284,19 @@ public class MessagesPublisher {
isSilent = true;
}
if (m_messagesStore.getUserVoipSilent(user)) {
LOG.info("The user {} is voip sliented", user);
isVoipSilent = true;
}
if (!isSilent && isPcOnline && m_messagesStore.getSilentWhenPcOnline(user)) {
LOG.info("The user {} pc online and silent when pc online", user);
isSilent = true;
}
if (!isSilent && m_messagesStore.isUserNoDisturbing(user)) {
if (m_messagesStore.isUserNoDisturbing(user)) {
LOG.info("The user {} is no disturbing", user);
isSilent = true;
isNoDisturb = true;
}
}
@@ -331,8 +342,9 @@ public class MessagesPublisher {
isConvSilent = false;
}
}
boolean isVoip = messageContentType == 402 || messageContentType == 400 || messageContentType == 401 || messageContentType == 406;
if ((StringUtil.isNullOrEmpty(pushContent) && messageContentType != 402 && messageContentType != 400 && messageContentType != 401 && messageContentType != 406)) {
if (StringUtil.isNullOrEmpty(pushContent) && StringUtil.isNullOrEmpty(pushData) && !isVoip) {
LOG.info("push content is empty and contenttype is {}", messageContentType);
continue;
}
@@ -342,16 +354,26 @@ public class MessagesPublisher {
continue;
}
if (isConvSilent) {
if (isConvSilent && !isVoip) {
LOG.info("Silent of user or conversation");
continue;
}
if (isSilent) {
if (isSilent && !isVoip) {
LOG.info("Silent of user");
continue;
}
if(isVoip && isVoipSilent) {
LOG.info("voip silent of user");
continue;
}
if(isNoDisturb) {
LOG.info("no disturb of user");
continue;
}
boolean isHiddenDetail = m_messagesStore.getUserPushHiddenDetail(user);
if(!nameLoaded) {
@@ -367,7 +389,7 @@ public class MessagesPublisher {
name = fd.getAlias();
}
}
this.messageSender.sendPush(sender, conversationType, target, line, messageHead, targetSession.getClientID(), pushContent, pushData, messageContentType, serverTime, name, targetName, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
this.messageSender.sendPush(sender, conversationType, target, line, messageId, targetSession.getClientID(), pushContent, pushData, messageContentType, serverTime, name, targetName, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
}
}
@@ -37,11 +37,12 @@ class PersistentQueueMessageSender {
this.connectionDescriptorStore = connectionDescriptorStore;
}
void sendPush(String sender, int conversationType, String target, int line, long messageHead, String deviceId, String pushContent, String pushData, int messageContentType, long serverTime, String senderName, String targetName, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
void sendPush(String sender, int conversationType, String target, int line, long messageId, String deviceId, String pushContent, String pushData, int messageContentType, long serverTime, String senderName, String targetName, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
LOG.info("Send push to {}, message from {}", deviceId, sender);
PushMessage pushMessage = new PushMessage(sender, conversationType, target, line, messageContentType, serverTime, senderName, targetName, unReceivedMsg, mentionType, isHiddenDetail, language);
pushMessage.pushContent = pushContent;
pushMessage.pushData = pushData;
pushMessage.messageId = messageId;
PushServer.getServer().pushMessage(pushMessage, deviceId, pushContent);
}
@@ -8,6 +8,8 @@
package win.liyufan.im;
import io.moquette.server.Server;
import java.io.*;
import java.util.Properties;
@@ -34,6 +36,8 @@ public class GitRepositoryState {
public final String buildTime;
public final String buildHost;
public final String buildVersion;
public final long runTime;
private GitRepositoryState(Properties properties) {
this.tags = String.valueOf(properties.get("git.tags"));
@@ -58,6 +62,7 @@ public class GitRepositoryState {
this.buildTime = String.valueOf(properties.get("git.build.time"));
this.buildHost = String.valueOf(properties.get("git.build.host"));
this.buildVersion = String.valueOf(properties.get("git.build.version"));
this.runTime = Server.getServer().getRunTime();
}
public static GitRepositoryState getGitRepositoryState() throws IOException {
@@ -10,4 +10,9 @@ public interface UserSettingScope {
int kUserSettingPCOnline = 10;
int kUserSettingMuteWhenPCOnline = 15;
int kUserSettingNoDisturbing = 17;
int kUserSettingConversationClearMessage = 18;
int kUserSettingConversationDraft = 19;
int kUserSettingDisableSyncDraft = 20;
int kUserSettingVoipSilent = 21;
}
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.70</version>
<version>0.71</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -20,6 +20,7 @@ public enum ErrorCode {
//Auth error
ERROR_CODE_TOKEN_ERROR(6, "token error"),
ERROR_CODE_KICKED_OFF(7, "kicked off"),
ERROR_CODE_USER_FORBIDDEN(8, "user forbidden"),
//Message error
+1 -1
View File
@@ -6,7 +6,7 @@
<!--<relativePath>../pom.xml</relativePath>-->
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.70</version>
<version>0.71</version>
</parent>
<artifactId>distribution</artifactId>
@@ -94,6 +94,12 @@ message.blacklist_exception_types 401,402,403,404,405,407,408,410,411
message.group_mute_exception_types 401,402,403,404,405,407,408,410,411
## 用户被全局禁言时允许发送的消息类型
message.global_mute_exception_types 401,402,403,404,405,407,408,410,411
## 消息转发功能开启时,开关是否不转发server api接口消息。
## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。
message.no_forward_admin_message false
##禁止搜索用户
friend.disable_search false
@@ -212,6 +218,10 @@ server.multi_platform_notification true
# 如果这里改为false,客户端那边需要同步修改pc在线默认通知状态,方法是client的setDefaultSilentWhenPcOnline函数。
server.mobile_default_silent_when_pc_online true
## 客户端是否支持kickoff事件。当客户端被其他端登录踢出时,如果此开关为false时,客户端协议栈上报secret_mismatch。如果此开关为ture时,客户端协议栈上报kicked_off。
## 客户端被踢时上报kicked_off是在2021.9.15之后才加上的。如果客户端协议栈全部为此日期之后的版本才可以打开此开关。
server.client_support_kickoff_event false
#*********************************************************************
# Push server configuration
#*********************************************************************
+1 -1
View File
@@ -12,7 +12,7 @@
<artifactId>wildfirechat-parent</artifactId>
<packaging>pom</packaging>
<version>0.70</version>
<version>0.71</version>
<name>Wildfire Chat</name>
<description>Wildfire Chat Server</description>
<inceptionYear>2019</inceptionYear>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.70</version>
<version>0.71</version>
</parent>
<modelVersion>4.0.0</modelVersion>