Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c02e9066be | ||
|
|
ffd1492ea2 | ||
|
|
5e9bbcb1e9 | ||
|
|
63770c75fa | ||
|
|
bf0eb5b8aa | ||
|
|
8cbf66930f | ||
|
|
ce48f67b04 | ||
|
|
2fdf11006d | ||
|
|
4a2d7a4cc5 | ||
|
|
0513da8993 |
@@ -111,7 +111,7 @@ friend.disable_search false
|
||||
##禁止按照昵称搜索用户。
|
||||
friend.disable_nick_name_search false
|
||||
|
||||
##禁止发送好友邀请,通过server api添加好友不受此限制
|
||||
##禁止发送好友邀请,通过server api添加好友不受此限制(force参数需要为true)
|
||||
friend.disable_friend_request false
|
||||
|
||||
##好友请求重复发送的间隔,单位是毫秒,默认是7天,0为不限制
|
||||
@@ -154,6 +154,20 @@ group.visible_quit_or_kickoff_notification 0
|
||||
# 因此需要分段多次同步,此开关定义了每次同步的数据的条数。此需要客户端支持,客户端SDK在2021.5.25日后支持此功能。如果确认所有客户端都在这个日志之后才可以打开此设置。
|
||||
#sync.data_part_size 1000
|
||||
|
||||
#*********************************************************************
|
||||
# 限频配置
|
||||
#*********************************************************************
|
||||
##API接口限频设置,时间是10秒内允许的请求次数。
|
||||
##管理api频率限制,默认是10秒10000次。
|
||||
http.admin.rate_limit 10000
|
||||
##机器人api频率限制,默认是10秒1000次,按照机器人ID区分。
|
||||
http.robot.rate_limit 1000
|
||||
##频道api频率限制,默认是10秒1000次,按照频道ID区分。
|
||||
http.channel.rate_limit 1000
|
||||
|
||||
##客户端请求频率限制,默认是5秒100次。通常情况下不要修改这个值。
|
||||
client.request_rate_limit 100
|
||||
|
||||
#*********************************************************************
|
||||
# hazelcase configuration
|
||||
#*********************************************************************
|
||||
@@ -163,7 +177,8 @@ hazelcast.configuration config/hazelcast.xml
|
||||
# Media server configuration
|
||||
#*********************************************************************
|
||||
##是否使用七牛云存储。1使用七牛;0使用内存文件服务器。默认的七牛账户信息不可用,请在七牛官网申请账户并配置
|
||||
##配置使用七牛请参考:https://docs.wildfirechat.cn/server/media_server.html
|
||||
##专业版另外支持阿里云存储和野火私有存储,关于野火私有存储请参考:https://github.com/wildfirechat/WF-minio
|
||||
##关于对象存储的详细信息请参考:https://docs.wildfirechat.cn/server/oss.html
|
||||
media.server.use_qiniu 0
|
||||
|
||||
##媒体类型分类
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.72</version>
|
||||
<version>0.74</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.RequireAuthentication;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.server.config.IConfig;
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.moquette.spi.ISessionsStore;
|
||||
import io.moquette.spi.impl.Utils;
|
||||
@@ -21,10 +22,12 @@ import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.RateLimiter;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
import static io.moquette.BrokerConstants.*;
|
||||
|
||||
/**
|
||||
* 请求处理接口<br>
|
||||
@@ -38,6 +41,36 @@ abstract public class Action {
|
||||
public static ISessionsStore sessionsStore = null;
|
||||
|
||||
public ChannelHandlerContext ctx;
|
||||
|
||||
protected static RateLimiter adminLimiter = null;
|
||||
protected static RateLimiter robotLimiter = null;
|
||||
protected static RateLimiter channelLimiter = null;
|
||||
|
||||
public static void init(IConfig config) {
|
||||
int adminRate = 10000;
|
||||
int robotRate = 1000;
|
||||
int channelRate = 1000;
|
||||
|
||||
try {
|
||||
adminRate = Integer.parseInt(config.getProperty(HTTP_ADMIN_RATE_LIMIT, "10000"));
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
robotRate = Integer.parseInt(config.getProperty(HTTP_ROBOT_RATE_LIMIT, "1000"));
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
channelRate = Integer.parseInt(config.getProperty(HTTP_CHANNEL_RATE_LIMIT, "1000"));
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
}
|
||||
adminLimiter = new RateLimiter(10, adminRate);
|
||||
robotLimiter = new RateLimiter(10, robotRate);
|
||||
channelLimiter = new RateLimiter(10, channelRate);
|
||||
}
|
||||
|
||||
protected class Result {
|
||||
Object data;
|
||||
ErrorCode errorCode;
|
||||
|
||||
@@ -29,7 +29,6 @@ abstract public class AdminAction extends Action {
|
||||
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(AdminAction.class);
|
||||
private static String SECRET_KEY = "123456";
|
||||
private static boolean NO_CHECK_TIME = false;
|
||||
private final RateLimiter mLimitCounter = new RateLimiter(10, 500);
|
||||
public static void setSecretKey(String secretKey) {
|
||||
SECRET_KEY = secretKey;
|
||||
}
|
||||
@@ -44,7 +43,7 @@ abstract public class AdminAction extends Action {
|
||||
|
||||
@Override
|
||||
public ErrorCode preAction(Request request, Response response) {
|
||||
if (!mLimitCounter.isGranted("admin")) {
|
||||
if (!adminLimiter.isGranted("admin")) {
|
||||
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
}
|
||||
|
||||
@@ -88,14 +87,16 @@ abstract public class AdminAction extends Action {
|
||||
}
|
||||
|
||||
protected void sendResponse(Response response, ErrorCode errorCode, Object data) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if (errorCode == null) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
if(response != null) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if (errorCode == null) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), data);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
response.send();
|
||||
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), data);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
response.send();
|
||||
}
|
||||
}
|
||||
protected void sendApiMessage(Response response, String fromUser, String topic, byte[] message, ApiCallback callback) {
|
||||
sendApiMessage(response, fromUser, null, topic, message, callback, false);
|
||||
|
||||
@@ -12,16 +12,22 @@ import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetFriendList;
|
||||
import cn.wildfirechat.pojos.InputUpdateAlias;
|
||||
import cn.wildfirechat.pojos.OutputCreateChannel;
|
||||
import cn.wildfirechat.pojos.OutputStringList;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -39,8 +45,26 @@ public class AliasPutAction extends AdminAction {
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputUpdateAlias input = getRequestBody(request.getNettyRequest(), InputUpdateAlias.class);
|
||||
ErrorCode errorCode = messagesStore.setFriendAliasRequest(input.getOperator(), input.getTargetId(), input.getAlias(), new long[1]);
|
||||
setResponseContent(RestResult.resultOf(errorCode), response);
|
||||
if(!StringUtil.isNullOrEmpty(input.getOperator()) && !StringUtil.isNullOrEmpty(input.getTargetId())) {
|
||||
WFCMessage.AddFriendRequest addFriendRequest = WFCMessage.AddFriendRequest.newBuilder().setTargetUid(input.getTargetId()).setReason(input.getAlias()==null?"":input.getAlias()).build();
|
||||
sendApiMessage(response, input.getOperator(), IMTopic.SetFriendAliasTopic, addFriendRequest.toByteArray(), result -> {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
byte[] data = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.readBytes(data);
|
||||
String channelId = new String(data);
|
||||
return new Result(ErrorCode.ERROR_CODE_SUCCESS, new OutputCreateChannel(channelId));
|
||||
} else {
|
||||
return new Result(errorCode);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
ErrorCode errorCode = messagesStore.setFriendAliasRequest(input.getOperator(), input.getTargetId(), input.getAlias(), new long[1]);
|
||||
setResponseContent(RestResult.resultOf(errorCode), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class BlockUserAction extends AdminAction {
|
||||
response.setContent(new Gson().toJson(result));
|
||||
|
||||
if (inputUserBlock.getStatus() == 2) {
|
||||
sendApiMessage(response, null, ServerAPIHelper.KICKOFF_USER_REQUEST, inputUserBlock.getUserId().getBytes(), null);
|
||||
sendApiMessage(null, null, ServerAPIHelper.KICKOFF_USER_REQUEST, inputUserBlock.getUserId().getBytes(), null);
|
||||
}
|
||||
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SUCCESS, null);
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.util.concurrent.Executor;
|
||||
|
||||
abstract public class ChannelAction extends Action {
|
||||
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ChannelAction.class);
|
||||
private final RateLimiter mLimitCounter = new RateLimiter(10, 200);
|
||||
protected WFCMessage.ChannelInfo channelInfo;
|
||||
|
||||
protected interface Callback {
|
||||
@@ -61,7 +60,7 @@ abstract public class ChannelAction extends Action {
|
||||
return ErrorCode.ERROR_CODE_API_NOT_SIGNED;
|
||||
}
|
||||
|
||||
if (!mLimitCounter.isGranted(cid)) {
|
||||
if (!channelLimiter.isGranted(cid)) {
|
||||
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.util.concurrent.Executor;
|
||||
|
||||
abstract public class RobotAction extends Action {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(RobotAction.class);
|
||||
private final RateLimiter mLimitCounter = new RateLimiter(10, 1000);
|
||||
|
||||
protected WFCMessage.Robot robot;
|
||||
|
||||
@@ -64,7 +63,7 @@ abstract public class RobotAction extends Action {
|
||||
return ErrorCode.ERROR_CODE_API_NOT_SIGNED;
|
||||
}
|
||||
|
||||
if (!mLimitCounter.isGranted(rid)) {
|
||||
if (!robotLimiter.isGranted(rid)) {
|
||||
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +178,10 @@ public final class BrokerConstants {
|
||||
public static final String MESSAGES_RECALL_TIME_LIMIT = "message.recall_time_limit";
|
||||
public static final String MESSAGES_DISABLE_GROUP_MANAGER_RECALL = "message.disable_group_manager_recall";
|
||||
|
||||
public static final String HTTP_ADMIN_RATE_LIMIT = "http.admin.rate_limit";
|
||||
public static final String HTTP_ROBOT_RATE_LIMIT = "http.robot.rate_limit";
|
||||
public static final String HTTP_CHANNEL_RATE_LIMIT = "http.channel.rate_limit";
|
||||
public static final String CLIENT_REQUEST_RATE_LIMIT = "client.request_rate_limit";
|
||||
|
||||
private BrokerConstants() {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Handler(value = IMTopic.ClearSessionTopic)
|
||||
public class DisconnectHandler extends IMHandler<Byte> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, Byte request, Qos1PublishHandler.IMCallback callback) {
|
||||
if (request == 8) {
|
||||
m_sessionsStore.cleanSession(fromUser, clientID);
|
||||
} else if(request == 1) {
|
||||
m_sessionsStore.disableSession(fromUser, clientID);
|
||||
}
|
||||
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import win.liyufan.im.I18n;
|
||||
import win.liyufan.im.IMTopic;
|
||||
import win.liyufan.im.MessageShardingUtil;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_ALREADY_FRIENDS;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(IMTopic.HandleFriendRequestTopic)
|
||||
@@ -86,6 +87,10 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
|
||||
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[1]);
|
||||
}
|
||||
}
|
||||
if(errorCode == ERROR_CODE_ALREADY_FRIENDS) {
|
||||
errorCode = ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import java.util.*;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
import static io.moquette.BrokerConstants.CLIENT_REQUEST_RATE_LIMIT;
|
||||
|
||||
/**
|
||||
* 请求处理接口<br>
|
||||
@@ -52,7 +53,7 @@ abstract public class IMHandler<T> {
|
||||
protected static Server mServer = null;
|
||||
protected static MessagesPublisher publisher;
|
||||
private static ThreadPoolExecutorWrapper m_imBusinessExecutor;
|
||||
private static final RateLimiter mLimitCounter = new RateLimiter(5, 100);
|
||||
private static RateLimiter mLimitCounter;
|
||||
private Method parseDataMethod;
|
||||
private Class dataCls;
|
||||
|
||||
@@ -147,12 +148,24 @@ abstract public class IMHandler<T> {
|
||||
publisher = p;
|
||||
m_imBusinessExecutor = businessExecutor;
|
||||
mServer = server;
|
||||
int clientRateLimit = 100;
|
||||
try {
|
||||
clientRateLimit = Integer.parseInt(server.getConfig().getProperty(CLIENT_REQUEST_RATE_LIMIT, "100"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
if(clientRateLimit == 0) {
|
||||
clientRateLimit = 100;
|
||||
}
|
||||
|
||||
mLimitCounter = new RateLimiter(5, clientRateLimit);
|
||||
}
|
||||
|
||||
|
||||
public ErrorCode preAction(String clientID, String fromUser, String topic, Qos1PublishHandler.IMCallback callback) {
|
||||
public ErrorCode preAction(String clientID, String fromUser, String topic, Qos1PublishHandler.IMCallback callback, boolean isAdmin, boolean isRobotOrChannel) {
|
||||
LOG.info("imHandler fromUser={}, clientId={}, topic={}", fromUser, clientID, topic);
|
||||
if(!mLimitCounter.isGranted(clientID + fromUser + topic)) {
|
||||
if(!isAdmin && !isRobotOrChannel && !mLimitCounter.isGranted(clientID + fromUser + topic)) {
|
||||
ByteBuf ackPayload = Unpooled.buffer();
|
||||
ackPayload.ensureWritable(1).writeByte(ERROR_CODE_OVER_FREQUENCY.getCode());
|
||||
try {
|
||||
@@ -166,7 +179,7 @@ abstract public class IMHandler<T> {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
public void doHandler(String clientID, String fromUser, String topic, byte[] payloadContent, Qos1PublishHandler.IMCallback callback, boolean isAdmin) {
|
||||
public void doHandler(String clientID, String fromUser, String topic, byte[] payloadContent, Qos1PublishHandler.IMCallback callback, boolean isAdmin, boolean isRobotOrChannel) {
|
||||
m_imBusinessExecutor.execute(() -> {
|
||||
Qos1PublishHandler.IMCallback callbackWrapper = new Qos1PublishHandler.IMCallback() {
|
||||
@Override
|
||||
@@ -177,7 +190,7 @@ abstract public class IMHandler<T> {
|
||||
}
|
||||
};
|
||||
|
||||
ErrorCode preActionCode = preAction(clientID, fromUser, topic, callbackWrapper);
|
||||
ErrorCode preActionCode = preAction(clientID, fromUser, topic, callbackWrapper, isAdmin, isRobotOrChannel);
|
||||
|
||||
if (preActionCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
ByteBuf ackPayload = Unpooled.buffer(1);
|
||||
|
||||
@@ -2819,6 +2819,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
}
|
||||
|
||||
if (friendData1 != null && friendData1.getState() == 0) {
|
||||
return ErrorCode.ERROR_CODE_ALREADY_FRIENDS;
|
||||
}
|
||||
|
||||
WFCMessage.FriendRequest newRequest = WFCMessage.FriendRequest
|
||||
.newBuilder()
|
||||
.setFromUid(userId)
|
||||
@@ -2856,7 +2860,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
public ErrorCode handleFriendRequest(String userId, WFCMessage.HandleFriendRequest request, WFCMessage.Message.Builder msgBuilder, long[] heads, boolean isAdmin) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
|
||||
|
||||
boolean alreadyFriend = false;
|
||||
if(!isAdmin && request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted) {
|
||||
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
|
||||
|
||||
@@ -2868,10 +2872,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
for (FriendData fd : friends) {
|
||||
if (fd.getFriendUid().equals(request.getTargetUid())) {
|
||||
if (fd.getState() == 0) {
|
||||
return ErrorCode.ERROR_CODE_ALREADY_FRIENDS;
|
||||
} else {
|
||||
break;
|
||||
alreadyFriend = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2950,7 +2953,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
if (existRequest != null) {
|
||||
if (mFriendRequestExpiration > 0 && System.currentTimeMillis() - existRequest.getUpdateDt() > mFriendRequestExpiration) {
|
||||
if (!alreadyFriend && mFriendRequestExpiration > 0 && System.currentTimeMillis() - existRequest.getUpdateDt() > mFriendRequestExpiration) {
|
||||
return ErrorCode.ERROR_CODE_FRIEND_REQUEST_EXPIRED;
|
||||
} else {
|
||||
existRequest = existRequest.toBuilder().setStatus(request.getStatus()).setUpdateDt(System.currentTimeMillis()).build();
|
||||
@@ -2976,7 +2979,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
}
|
||||
|
||||
if(request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted){
|
||||
if(!alreadyFriend && request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted){
|
||||
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
|
||||
FriendData friendData1 = new FriendData(userId, request.getTargetUid(), "", request.getExtra(), 0, 0, System.currentTimeMillis());
|
||||
databaseStore.persistOrUpdateFriendData(friendData1);
|
||||
@@ -2997,6 +3000,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
callbackRelationEvent(userId, request.getTargetUid(), 0, "1");
|
||||
}
|
||||
if(alreadyFriend) {
|
||||
return ErrorCode.ERROR_CODE_ALREADY_FRIENDS;
|
||||
}
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.hazelcast.config.FileSystemXmlConfig;
|
||||
import com.hazelcast.core.*;
|
||||
import com.xiaoleilu.loServer.LoServer;
|
||||
import com.xiaoleilu.loServer.ServerSetting;
|
||||
import com.xiaoleilu.loServer.action.Action;
|
||||
import com.xiaoleilu.loServer.action.admin.AdminAction;
|
||||
import io.moquette.BrokerConstants;
|
||||
import io.moquette.persistence.*;
|
||||
@@ -257,6 +258,7 @@ public class Server {
|
||||
|
||||
initMediaServerConfig(config);
|
||||
|
||||
Action.init(config);
|
||||
String monitorEventAddress = config.getProperty(MONITOR_Exception_Event_Address);
|
||||
Utility.setMonitorEventAddress(monitorEventAddress);
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ public class Qos1PublishHandler extends QosPublishHandler {
|
||||
private final MessagesPublisher publisher;
|
||||
private final ISessionsStore m_sessionStore;
|
||||
private final ThreadPoolExecutorWrapper m_imBusinessExecutor;
|
||||
private final RateLimiter mLimitCounter = new RateLimiter(5, 100);
|
||||
|
||||
private HashMap<String, IMHandler> m_imHandlers = new HashMap<>();
|
||||
|
||||
@@ -148,19 +147,6 @@ public class Qos1PublishHandler extends QosPublishHandler {
|
||||
|
||||
void imHandler(String clientID, String fromUser, String topic, byte[] payloadContent, IMCallback callback, boolean isAdmin, boolean isRobotOrChannel) {
|
||||
LOG.info("imHandler fromUser={}, topic={}", fromUser, topic);
|
||||
if(!isAdmin && !isRobotOrChannel && !mLimitCounter.isGranted(clientID + fromUser + topic)) {
|
||||
ByteBuf ackPayload = Unpooled.buffer();
|
||||
ackPayload.ensureWritable(1).writeByte(ERROR_CODE_OVER_FREQUENCY.getCode());
|
||||
try {
|
||||
callback.onIMHandled(ERROR_CODE_OVER_FREQUENCY, ackPayload);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
LOG.warn("user {} request over frequency", fromUser);
|
||||
return;
|
||||
}
|
||||
|
||||
IMCallback wrapper = (errorcode, ackPayload) -> {
|
||||
ackPayload.resetReaderIndex();
|
||||
byte code = ackPayload.readByte();
|
||||
@@ -215,7 +201,7 @@ public class Qos1PublishHandler extends QosPublishHandler {
|
||||
|
||||
IMHandler handler = m_imHandlers.get(topic);
|
||||
if (handler != null) {
|
||||
handler.doHandler(clientID, fromUser, topic, payloadContent, wrapper, isAdmin);
|
||||
handler.doHandler(clientID, fromUser, topic, payloadContent, wrapper, isAdmin, isRobotOrChannel);
|
||||
} else {
|
||||
LOG.error("imHandler unknown topic={}", topic);
|
||||
ByteBuf ackPayload = Unpooled.buffer();
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.72</version>
|
||||
<version>0.74</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<!--<relativePath>../pom.xml</relativePath>-->
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.72</version>
|
||||
<version>0.74</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>distribution</artifactId>
|
||||
|
||||
@@ -106,7 +106,7 @@ friend.disable_search false
|
||||
##禁止按照昵称搜索用户。
|
||||
friend.disable_nick_name_search false
|
||||
|
||||
##禁止发送好友邀请,通过server api添加好友不受此限制
|
||||
##禁止发送好友邀请,通过server api添加好友不受此限制(force参数需要为true)
|
||||
friend.disable_friend_request false
|
||||
|
||||
##好友请求重复发送的间隔,单位是毫秒,默认是7天,0为不限制
|
||||
@@ -150,6 +150,20 @@ group.visible_quit_or_kickoff_notification 0
|
||||
# 因此需要分段多次同步,此开关定义了每次同步的数据的条数。此需要客户端支持,客户端SDK在2021.5.25日后支持此功能。如果确认所有客户端都在这个日志之后才可以打开此设置。
|
||||
#sync.data_part_size 1000
|
||||
|
||||
#*********************************************************************
|
||||
# 限频配置
|
||||
#*********************************************************************
|
||||
##API接口限频设置,时间是10秒内允许的请求次数。
|
||||
##管理api频率限制,默认是10秒10000次。
|
||||
http.admin.rate_limit 10000
|
||||
##机器人api频率限制,默认是10秒1000次,按照机器人ID区分。
|
||||
http.robot.rate_limit 1000
|
||||
##频道api频率限制,默认是10秒1000次,按照频道ID区分。
|
||||
http.channel.rate_limit 1000
|
||||
|
||||
##客户端请求频率限制,默认是5秒100次。通常情况下不要修改这个值。
|
||||
client.request_rate_limit 100
|
||||
|
||||
#*********************************************************************
|
||||
# hazelcase configuration
|
||||
#*********************************************************************
|
||||
@@ -159,7 +173,8 @@ hazelcast.configuration config/hazelcast.xml
|
||||
# Media server configuration
|
||||
#*********************************************************************
|
||||
##是否使用七牛云存储。1使用七牛;0使用内存文件服务器。默认的七牛账户信息不可用,请在七牛官网申请账户并配置
|
||||
##配置使用七牛请参考:https://docs.wildfirechat.cn/server/media_server.html
|
||||
##专业版另外支持阿里云存储和野火私有存储,关于野火私有存储请参考:https://github.com/wildfirechat/WF-minio
|
||||
##关于对象存储的详细信息请参考:https://docs.wildfirechat.cn/server/oss.html
|
||||
media.server.use_qiniu 0
|
||||
|
||||
##媒体类型分类
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<version>0.72</version>
|
||||
<version>0.74</version>
|
||||
<name>Wildfire Chat</name>
|
||||
<description>Wildfire Chat Server</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.72</version>
|
||||
<version>0.74</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -292,7 +292,7 @@ public class Main {
|
||||
}
|
||||
|
||||
IMResult<Void> result = RelationAdmin.sendFriendRequest("ff1", "ff2", "hello", true);
|
||||
if (result != null && result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
if (result != null && (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS || result.getErrorCode() == ErrorCode.ERROR_CODE_ALREADY_FRIENDS)) {
|
||||
System.out.println("send friend request success");
|
||||
} else {
|
||||
System.out.println("failure");
|
||||
@@ -308,7 +308,7 @@ public class Main {
|
||||
}
|
||||
|
||||
result = RelationAdmin.sendFriendRequest("ff1", "ff2", "hello3", true);
|
||||
if (result != null && result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
if (result != null && (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS || result.getErrorCode() == ErrorCode.ERROR_CODE_ALREADY_FRIENDS)) {
|
||||
System.out.println("success");
|
||||
} else {
|
||||
System.out.println("send friend request success");
|
||||
|
||||
Reference in New Issue
Block a user