Compare commits

..
17 Commits
35 changed files with 388 additions and 53 deletions
+4 -1
View File
@@ -36,7 +36,7 @@ host 0.0.0.0
local_port 80
##是否使用内置DB。0使用mysql;1使用h2db;2使用mysql+mongodb。社区版只支持0和1,专业版支持2
embed.db 0
embed.db 1
##服务器管理接口密钥
http.admin.secret_key 123456
@@ -74,6 +74,9 @@ friend.repeat_request_duration 604800000
##好友请求被拒绝后再次发送的间隔,单位是毫秒,默认是30天,0为不限制
friend.reject_request_duration 2592000000
##好友请求过期时间,单位是毫秒,默认是7天,0为不限制
friend.request_expiration_duration 604800000
## 聊天室观众空闲退出时间,单位为毫秒,默认为15分钟,0为永远不退出
chatroom.participant_idle_time 900000
+26 -5
View File
@@ -9,19 +9,40 @@ server {
root html;
index index.html index.htm index.php;
## send request back to im server ##
location /im {
location /route {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver;
}
location /route {
#社区版需要启用下面一段,专业版不能用
location /im {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver;
}
location /api {
proxy_pass http://imserver;
}
location / {
proxy_pass https://wildfirechat.github.io/docs/;
location /fs {
proxy_pass http://imserver;
}
location /robot {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver;
}
location /channel {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver;
}
}
+1 -1
View File
@@ -41,7 +41,7 @@
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
@@ -21,6 +21,7 @@ import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import com.xiaoleilu.loServer.action.ClassUtil;
import org.slf4j.LoggerFactory;
import win.liyufan.im.Utility;
import java.io.IOException;
@@ -141,6 +142,7 @@ public class LoServer {
}
} catch (IOException e) {
e.printStackTrace();
Utility.printExecption(Logger, e);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
@@ -0,0 +1,75 @@
/*
* 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 com.xiaoleilu.loServer.action;
import com.google.gson.Gson;
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 io.moquette.persistence.MemorySessionStore;
import io.moquette.spi.security.Tokenor;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
import win.liyufan.im.GitRepositoryState;
import win.liyufan.im.RateLimiter;
import win.liyufan.im.Utility;
import java.io.IOException;
@Route("/api/verify_token")
@HttpMethod("GET")
public class CheckTokenAction extends Action {
private final RateLimiter mLimitCounter = new RateLimiter(10, 1);
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
response.setStatus(HttpResponseStatus.OK);
String userId = request.getParam("userId");
String clientId = request.getParam("clientId");
String token = request.getParam("token");
String result = "这是个检查token有效性的接口,如果客户端无法连接成功,可以使用这个接口检查token是否正确。\n";
result += "使用方法是在浏览器中输入http://imserverip/api/verify_token?userId=${userId}&clientId=${clientId}&token=${token}。\n";
result += "例如:http://localhost/api/verify_token?userId=123&clientId=456&token=789。\n";
result += "特别注意的是:必须使用正确的clientId,clientId必须是在测试手机上调用im接口获取。不用手机上获取到的clientId也都是不同的,一定不能用错!!!\n\n\n";
if (StringUtil.isNullOrEmpty(userId)) {
result += "错误,userId为空";
} else if (StringUtil.isNullOrEmpty(clientId)) {
result += "错误,clientId为空";
} else if (StringUtil.isNullOrEmpty(token)) {
result += "错误,token为空";
} else if(!mLimitCounter.isGranted("verify_token")) {
result += "接口请求超频!接口限制每10秒只能验证一次!";
} else {
MemorySessionStore.Session session = sessionsStore.getSession(clientId);
if (session == null) {
result += "错误,session不存在。请确认token是从本服务通过getToken接口获取的,另外请确认clientId是否正确";
} else if (session.getDeleted() == 1) {
result += "错误,session已经被清除,请确认当前客户没有多端登录或者主动退出";
} else if(!session.getUsername().equals(userId)) {
result += "错误,当前客户端的登录用户不是" + userId + "。这一般发生在当前clientId又为其它用户获取过token";
} else {
String id = Tokenor.getUserId(token.getBytes());
if (id == null) {
result += "错误,无效的token";
} else if(!id.equals(userId)) {
result += "错误,改token是用户" + id + "的";
} else {
result += "恭喜,您的信息是正确的";
}
}
}
response.setContent(result);
}
return true;
}
}
@@ -28,7 +28,7 @@ public class UnknownErrorAction extends Action{
@Override
public boolean action(Request request, Response response) {
response.setStatus(HttpResponseStatus.NOT_FOUND);
response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
return true;
}
}
@@ -9,6 +9,7 @@
package com.xiaoleilu.loServer.action.admin;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.LoServer;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.handler.Request;
@@ -17,9 +18,12 @@ import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
import org.apache.commons.codec.digest.DigestUtils;
import cn.wildfirechat.common.ErrorCode;
import org.slf4j.LoggerFactory;
import win.liyufan.im.RateLimiter;
import win.liyufan.im.Utility;
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);
@@ -52,6 +56,7 @@ abstract public class AdminAction extends Action {
ts = Long.parseLong(timestamp);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
return ErrorCode.INVALID_PARAMETER;
}
@@ -22,11 +22,15 @@ import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
import cn.wildfirechat.common.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.UUIDGenerator;
import win.liyufan.im.Utility;
@Route(APIPath.Create_Robot)
@HttpMethod("POST")
public class CreateRobotAction extends AdminAction {
private static final Logger LOG = LoggerFactory.getLogger(CreateRobotAction.class);
@Override
public boolean isTransactionAction() {
@@ -55,7 +59,16 @@ public class CreateRobotAction extends AdminAction {
WFCMessage.User newUser = inputCreateRobot.toUser();
messagesStore.addUserInfo(newUser, inputCreateRobot.getPassword());
try {
messagesStore.addUserInfo(newUser, inputCreateRobot.getPassword());
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
response.setContent(new Gson().toJson(result));
return true;
}
if (StringUtil.isNullOrEmpty(inputCreateRobot.getOwner())) {
inputCreateRobot.setOwner(inputCreateRobot.getUserId());
@@ -9,6 +9,7 @@
package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
@@ -22,11 +23,16 @@ import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
import cn.wildfirechat.common.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.DBUtil;
import win.liyufan.im.UUIDGenerator;
import win.liyufan.im.Utility;
@Route(APIPath.Create_User)
@HttpMethod("POST")
public class CreateUserAction extends AdminAction {
private static final Logger LOG = LoggerFactory.getLogger(CreateUserAction.class);
@Override
public boolean isTransactionAction() {
@@ -38,7 +44,8 @@ public class CreateUserAction extends AdminAction {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputOutputUserInfo inputCreateUser = getRequestBody(request.getNettyRequest(), InputOutputUserInfo.class);
if (inputCreateUser != null
&& !StringUtil.isNullOrEmpty(inputCreateUser.getName())) {
&& !StringUtil.isNullOrEmpty(inputCreateUser.getName())
&& (inputCreateUser.getType() == ProtoConstants.UserType.UserType_Normal || inputCreateUser.getType() == ProtoConstants.UserType.UserType_Admin || inputCreateUser.getType() == ProtoConstants.UserType.UserType_Super_Admin)) {
if(StringUtil.isNullOrEmpty(inputCreateUser.getPassword())) {
inputCreateUser.setPassword(UUIDGenerator.getUUID());
@@ -73,9 +80,20 @@ public class CreateUserAction extends AdminAction {
if (inputCreateUser.getExtra() != null)
newUserBuilder.setExtra(inputCreateUser.getExtra());
newUserBuilder.setType(inputCreateUser.getType());
newUserBuilder.setUpdateDt(System.currentTimeMillis());
messagesStore.addUserInfo(newUserBuilder.build(), inputCreateUser.getPassword());
try {
messagesStore.addUserInfo(newUserBuilder.build(), inputCreateUser.getPassword());
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
response.setContent(new Gson().toJson(result));
return true;
}
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.ok(new OutputCreateUser(inputCreateUser.getUserId(), inputCreateUser.getName()));
@@ -12,6 +12,7 @@ import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.admin.AdminAction;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.moquette.spi.impl.Utils;
@@ -21,9 +22,12 @@ import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
import org.apache.commons.codec.digest.DigestUtils;
import cn.wildfirechat.common.ErrorCode;
import org.slf4j.LoggerFactory;
import win.liyufan.im.RateLimiter;
import win.liyufan.im.Utility;
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;
@@ -47,6 +51,7 @@ abstract public class ChannelAction extends Action {
ts = Long.parseLong(timestamp);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
return ErrorCode.INVALID_PARAMETER;
}
@@ -10,6 +10,7 @@ package com.xiaoleilu.loServer.action.channel;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.pojos.SendChannelMessageData;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
@@ -44,11 +45,15 @@ public class SendMessageAction extends ChannelAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
SendMessageData sendMessageData = getRequestBody(request.getNettyRequest(), SendMessageData.class);
SendChannelMessageData sendChannelMessageData = getRequestBody(request.getNettyRequest(), SendChannelMessageData.class);
SendMessageData sendMessageData = new SendMessageData();
sendMessageData.setConv(new Conversation());
sendMessageData.getConv().setType(ConversationType_Channel);
sendMessageData.getConv().setTarget(channelInfo.getTargetId());
sendMessageData.getConv().setLine(sendChannelMessageData.getLine());
sendMessageData.setSender(channelInfo.getOwner());
sendMessageData.setPayload(sendChannelMessageData.getPayload());
sendMessageData.setToUsers(sendChannelMessageData.getTargets());
if (SendMessageData.isValide(sendMessageData)) {
RPCCenter.getInstance().sendRequest(sendMessageData.getSender(), null, IMTopic.SendMessageTopic, sendMessageData.toProtoMessage().toByteArray(), sendMessageData.getSender(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
@@ -14,6 +14,7 @@ import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.moquette.imhandler.IMHandler;
import io.moquette.spi.impl.Utils;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpRequest;
@@ -21,11 +22,15 @@ import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
import org.apache.commons.codec.digest.DigestUtils;
import cn.wildfirechat.common.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.RateLimiter;
import win.liyufan.im.Utility;
import java.io.UnsupportedEncodingException;
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;
@@ -49,6 +54,7 @@ abstract public class RobotAction extends Action {
ts = Long.parseLong(timestamp);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
return ErrorCode.INVALID_PARAMETER;
}
@@ -89,6 +95,7 @@ abstract public class RobotAction extends Action {
return t;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
return null;
@@ -21,6 +21,7 @@ import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.Utility;
/**
* Action处理单元
@@ -52,6 +53,7 @@ abstract public class ActionHandler extends SimpleChannelInboundHandler<FullHttp
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(Logger, e);
Action errorAction = ServerSetting.getErrorAction(ServerSetting.MAPPING_ERROR);
request.putParam(UnknownErrorAction.ERROR_PARAM_NAME, e);
response.setContent(e.toString());
@@ -20,6 +20,7 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,7 +38,7 @@ public class IMActionHandler extends ActionHandler {
@Override
boolean isValidePath(String path) {
if (!path.startsWith("/admin")) {
if (!StringUtil.isNullOrEmpty(path) && !path.startsWith("/admin")) {
return true;
}
return false;
@@ -124,6 +124,7 @@ public final class BrokerConstants {
public static final String MESSAGE_Blacklist_Strategy = "message.blacklist.strategy";
public static final String FRIEND_Repeat_Request_Duration = "friend.repeat_request_duration";
public static final String FRIEND_Reject_Request_Duration = "friend.reject_request_duration";
public static final String FRIEND_Request_Expiration_Duration = "friend.request_expiration_duration";
public static final String CHATROOM_Participant_Idle_Time = "chatroom.participant_idle_time";
public static final String CHATROOM_Rejoin_When_Active = "chatroom.rejoin_when_active";
@@ -8,6 +8,7 @@
package io.moquette.imhandler;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
@@ -24,6 +25,13 @@ public class LoadRemoteMessagesHandler extends IMHandler<WFCMessage.LoadRemoteMe
if (beforeUid == 0) {
beforeUid = Long.MAX_VALUE;
}
if (request.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Group) {
if (!m_messagesStore.isMemberInGroup(fromUser, request.getConversation().getTarget())) {
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
}
}
WFCMessage.PullMessageResult result = m_messagesStore.loadRemoteMessages(fromUser, request.getConversation(), beforeUid, request.getCount());
byte[] data = result.toByteArray();
LOG.info("User {} load message with count({}), payload size({})", fromUser, result.getMessageCount(), data.length);
@@ -31,7 +31,7 @@ public class ModifyGroupInfoHandler extends GroupHandler<WFCMessage.ModifyGroupI
if (request.getType() == Modify_Group_Name) {
content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getValue(), "").getChangeGroupNameNotifyContent();
} else if(request.getType() == Modify_Group_Portrait) {
content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getChangeGroupPortraitNotifyContent();
content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getValue(), "").getChangeGroupPortraitNotifyContent();
} else if(request.getType() == Modify_Group_Mute) {
content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getValue(), "").getChangeGroupMuteNotifyContent();
} else if(request.getType() == Modify_Group_JoinType) {
@@ -13,11 +13,18 @@ import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import cn.wildfirechat.common.ErrorCode;
import win.liyufan.im.IMTopic;
import win.liyufan.im.Utility;
@Handler(IMTopic.ModifyMyInfoTopic)
public class ModifyMyInfoHandler extends IMHandler<WFCMessage.ModifyMyInfoRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyMyInfoRequest request, Qos1PublishHandler.IMCallback callback) {
try {
return m_messagesStore.modifyUserInfo(fromUser, request);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
return ErrorCode.ERROR_CODE_SERVER_ERROR;
}
}
}
@@ -17,6 +17,7 @@ import io.netty.buffer.ByteBuf;
import cn.wildfirechat.common.ErrorCode;
import win.liyufan.im.IMTopic;
import win.liyufan.im.MessageShardingUtil;
import win.liyufan.im.Utility;
import java.util.Set;
@@ -39,12 +40,14 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
mSensitiveType = Integer.parseInt(mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Filter_Type));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
mBlacklistStrategy = Integer.parseInt(mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Blacklist_Strategy));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
@@ -68,6 +71,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
if (errorCode == ErrorCode.ERROR_CODE_IN_BLACK_LIST && mBlacklistStrategy != ProtoConstants.BlacklistStrategy.Message_Reject) {
ignoreMsg = true;
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
} else {
return errorCode;
}
@@ -2128,7 +2128,7 @@ public class DatabaseStore {
});
}
void updateUser(final WFCMessage.User user) {
void updateUser(final WFCMessage.User user) throws Exception {
LOG.info("Database update user info {} {}", user.getUid(), user.getUpdateDt());
Connection connection = null;
PreparedStatement statement = null;
@@ -2202,6 +2202,7 @@ public class DatabaseStore {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
throw new Exception(e.getMessage());
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -22,7 +22,6 @@ import cn.wildfirechat.proto.WFCMessage;
import com.google.protobuf.ByteString;
import com.hazelcast.core.*;
import com.hazelcast.util.StringUtil;
import com.xiaoleilu.hutool.system.UserInfo;
import com.xiaoleilu.loServer.model.FriendData;
import cn.wildfirechat.pojos.InputOutputUserBlockStatus;
import cn.wildfirechat.common.ErrorCode;
@@ -122,6 +121,8 @@ public class MemoryMessagesStore implements IMessagesStore {
private long mFriendRequestDuration = 7 * 24 * 60 * 60 * 1000;
private long mFriendRejectDuration = 30 * 24 * 60 * 60 * 1000;
private long mFriendRequestExpiration = 7 * 24 * 60 * 60 * 1000;
private boolean mDisableStrangerChat = false;
private long mChatroomParticipantIdleTime = 900000;
@@ -138,30 +139,42 @@ public class MemoryMessagesStore implements IMessagesStore {
mDisableStrangerChat = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.MESSAGE_Disable_Stranger_Chat));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
mFriendRequestDuration = Long.parseLong(m_Server.getConfig().getProperty(FRIEND_Repeat_Request_Duration));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
mFriendRejectDuration = Long.parseLong(m_Server.getConfig().getProperty(FRIEND_Reject_Request_Duration));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
mFriendRequestExpiration = Long.parseLong(m_Server.getConfig().getProperty(FRIEND_Request_Expiration_Duration));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
mChatroomRejoinWhenActive = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.CHATROOM_Rejoin_When_Active));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
mChatroomParticipantIdleTime = Long.parseLong(m_Server.getConfig().getProperty(CHATROOM_Participant_Idle_Time, "900000"));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
@@ -245,8 +258,17 @@ public class MemoryMessagesStore implements IMessagesStore {
if (!StringUtil.isNullOrEmpty(message.getToUser())) {
notifyReceivers.add(message.getToUser());
} else if(!message.getToList().isEmpty()) {
notifyReceivers.addAll(message.getToList());
} else if(message.getToList()!=null && !message.getToList().isEmpty()) {
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
Collection<WFCMessage.GroupMember> members = groupMembers.get(message.getConversation().getTarget());
if (members == null || members.size() == 0) {
members = loadGroupMemberFromDB(hzInstance, message.getConversation().getTarget());
}
for (WFCMessage.GroupMember member : members) {
if (member.getType() != GroupMemberType_Removed && message.getToList().contains(member.getMemberId())) {
notifyReceivers.add(member.getMemberId());
}
}
} else {
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
Collection<WFCMessage.GroupMember> members = groupMembers.get(message.getConversation().getTarget());
@@ -283,14 +305,20 @@ public class MemoryMessagesStore implements IMessagesStore {
if (channelInfo != null) {
notifyReceivers.add(fromUser);
if (channelInfo.getOwner().equals(fromUser)) {
MultiMap<String, String> listeners = hzInstance.getMultiMap(CHANNEL_LISTENERS);
if (StringUtil.isNullOrEmpty(message.getToUser())) {
MultiMap<String, String> listeners = hzInstance.getMultiMap(CHANNEL_LISTENERS);
notifyReceivers.addAll(listeners.get(message.getConversation().getTarget()));
} else {
MultiMap<String, String> listeners = hzInstance.getMultiMap(CHANNEL_LISTENERS);
if (listeners.values().contains(message.getToUser())) {
notifyReceivers.add(message.getToUser());
}
} else if(message.getToList() != null && !message.getToList().isEmpty()) {
Collection<String> ls = listeners.get(message.getConversation().getTarget());
for (String to:message.getToList()) {
if (ls.contains(to)) {
notifyReceivers.add(to);
}
}
} else {
notifyReceivers.addAll(listeners.get(message.getConversation().getTarget()));
}
} else {
if (StringUtil.isNullOrEmpty(channelInfo.getCallback()) || channelInfo.getAutomatic() == 0) {
@@ -592,6 +620,14 @@ public class MemoryMessagesStore implements IMessagesStore {
MemorySessionStore.Session session = m_Server.getStore().sessionsStore().getSession(clientId);
String existChatroomId = (String)m_Server.getHazelcastInstance().getMap(USER_CHATROOM).get(user);
if (chatroomId == null) {
if (existChatroomId == null) {
return false;
} else {
chatroomId = existChatroomId;
}
}
if (StringUtil.isNullOrEmpty(existChatroomId) || !existChatroomId.equals(chatroomId)) {
if (mChatroomRejoinWhenActive) {
if (!StringUtil.isNullOrEmpty(existChatroomId)) {
@@ -1259,8 +1295,9 @@ public class MemoryMessagesStore implements IMessagesStore {
if (members == null || members.size() == 0) {
members = loadGroupMemberFromDB(hzInstance, groupId);
}
for (WFCMessage.GroupMember member : members
) {
boolean isInGroup = false;
for (WFCMessage.GroupMember member : members) {
if (member.getMemberId().equals(memberId)) {
if (member.getType() == GroupMemberType_Silent) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
@@ -1273,11 +1310,16 @@ public class MemoryMessagesStore implements IMessagesStore {
if (member.getMemberId().equals(memberId) && member.getType() == GroupMemberType_Removed) {
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
}
isInGroup = true;
break;
}
}
if (!isInGroup) {
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
}
return ErrorCode.ERROR_CODE_SUCCESS;
}
@@ -1411,7 +1453,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
@Override
public ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request) {
public ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request) throws Exception {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
@@ -1474,8 +1516,8 @@ public class MemoryMessagesStore implements IMessagesStore {
if (modified) {
builder.setUpdateDt(System.currentTimeMillis());
user = builder.build();
databaseStore.updateUser(user);
mUserMap.set(userId, user);
// databaseStore.updateUser(user);
return ErrorCode.ERROR_CODE_SUCCESS;
} else {
return ErrorCode.ERROR_CODE_NOT_MODIFIED;
@@ -1520,9 +1562,10 @@ public class MemoryMessagesStore implements IMessagesStore {
}
@Override
public void addUserInfo(WFCMessage.User user, String password) {
public void addUserInfo(WFCMessage.User user, String password) throws Exception {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
databaseStore.updateUser(user);
mUserMap.put(user.getUid(), user);
databaseStore.updateUserPassword(user.getUid(), password);
}
@@ -1533,7 +1576,13 @@ public class MemoryMessagesStore implements IMessagesStore {
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
WFCMessage.User us = mUserMap.get(userId);
if (us != null) {
us = WFCMessage.User.newBuilder().setUid(userId).setUpdateDt(System.currentTimeMillis()).setDisplayName("已删除用户").setName(userId).setDeleted(1).build();
us = WFCMessage.User.newBuilder().setUid(userId).setUpdateDt(System.currentTimeMillis()).setDisplayName("").setName(userId).setDeleted(1).build();
try {
databaseStore.updateUser(us);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
mUserMap.put(userId, us);
}
@@ -2048,8 +2097,8 @@ public class MemoryMessagesStore implements IMessagesStore {
}
if (existRequest != null) {
if (mFriendRequestDuration > 0 && System.currentTimeMillis() - existRequest.getUpdateDt() > mFriendRequestDuration) {
return ErrorCode.ERROR_CODE_FRIEND_REQUEST_OVERTIME;
if (mFriendRequestExpiration > 0 && System.currentTimeMillis() - existRequest.getUpdateDt() > mFriendRequestExpiration) {
return ErrorCode.ERROR_CODE_FRIEND_REQUEST_EXPIRED;
} else {
existRequest = existRequest.toBuilder().setStatus(ProtoConstants.FriendRequestStatus.RequestStatus_Accepted).setUpdateDt(System.currentTimeMillis()).build();
databaseStore.persistOrUpdateFriendRequest(existRequest);
@@ -2284,6 +2333,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
@@ -2494,6 +2544,7 @@ public class MemoryMessagesStore implements IMessagesStore {
newInfoBuilder.setAutomatic(Integer.parseInt(value));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
@@ -29,6 +29,7 @@ import io.moquette.spi.IMessagesStore.StoredMessage;
import io.netty.handler.codec.mqtt.MqttVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.Utility;
import java.util.*;
import java.util.concurrent.*;
@@ -272,6 +273,7 @@ public class MemorySessionStore implements ISessionsStore {
supportMultiEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_ENDPOINT));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
@@ -19,7 +19,7 @@ import java.util.Map;
public class UserLoader implements MapStore<String, WFCMessage.User> {
@Override
public void store(String s, WFCMessage.User user) {
getDatabaseStore().updateUser(user);
// getDatabaseStore().updateUser(user);
}
@Override
@@ -129,13 +129,13 @@ public interface IMessagesStore {
WFCMessage.Robot getRobot(String robotId);
void addRobot(WFCMessage.Robot robot);
ErrorCode getUserInfo(List<WFCMessage.UserRequest> requestList, WFCMessage.PullUserResult.Builder builder);
ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request);
ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request) throws Exception;
ErrorCode modifyUserStatus(String userId, int status);
int getUserStatus(String userId);
List<InputOutputUserBlockStatus> getUserStatusList();
void addUserInfo(WFCMessage.User user, String password);
void addUserInfo(WFCMessage.User user, String password) throws Exception;
void destoryUser(String userId);
WFCMessage.User getUserInfo(String userId);
WFCMessage.User getUserInfoByName(String name);
@@ -87,6 +87,7 @@ public class MessagesPublisher {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
chatroomScheduler.shutdown();
}
@@ -187,6 +187,7 @@ public class Qos1PublishHandler extends QosPublishHandler {
gzip.close();
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
data = out.toByteArray();
code = (byte)ErrorCode.ERROR_CODE_SUCCESS_GZIPED.code;
@@ -36,7 +36,7 @@ public enum ErrorCode {
//user error
ERROR_CODE_FRIEND_ALREADY_REQUEST(16, "already send request"),
ERROR_CODE_FRIEND_REQUEST_BLOCKED(18, "friend request blocked"),
ERROR_CODE_FRIEND_REQUEST_OVERTIME(19, "friend request overtime"),
ERROR_CODE_FRIEND_REQUEST_EXPIRED(19, "friend request expired"),
ERROR_CODE_NOT_IN_CHATROOM(20, "not in chatroom"),
@@ -24,6 +24,7 @@ public class InputOutputUserInfo {
private String company;
private String social;
private String extra;
private int type;
private long updateDt;
public static InputOutputUserInfo fromPbUser(WFCMessage.User pbUser) {
@@ -39,6 +40,7 @@ public class InputOutputUserInfo {
inputCreateUser.company = pbUser.getCompany();
inputCreateUser.social = pbUser.getSocial();
inputCreateUser.extra = pbUser.getExtra();
inputCreateUser.type = pbUser.getType();
inputCreateUser.updateDt = pbUser.getUpdateDt();
return inputCreateUser;
}
@@ -74,6 +76,7 @@ public class InputOutputUserInfo {
if (getExtra() != null)
newUserBuilder.setExtra(getExtra());
newUserBuilder.setGender(gender);
newUserBuilder.setType(type);
newUserBuilder.setUpdateDt(System.currentTimeMillis());
return newUserBuilder.build();
@@ -174,4 +177,12 @@ public class InputOutputUserInfo {
public void setGender(int gender) {
this.gender = gender;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
@@ -18,6 +18,7 @@ public class OutputGetChatroomInfo {
private String desc;
private String portrait;
private String extra;
private int state;
private int memberCount;
private long createDt;
private long updateDt;
@@ -28,6 +29,8 @@ public class OutputGetChatroomInfo {
this.desc = chatroomInfo.getDesc();
this.portrait = chatroomInfo.getPortrait();
this.memberCount = memberCount;
this.extra = chatroomInfo.getExtra();
this.state = chatroomInfo.getState();
this.createDt = chatroomInfo.getCreateDt();
this.updateDt = chatroomInfo.getUpdateDt();
}
@@ -98,4 +101,12 @@ public class OutputGetChatroomInfo {
public void setExtra(String extra) {
this.extra = extra;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
@@ -12,10 +12,13 @@ import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
import java.util.List;
public class SendMessageData {
private String sender;
private Conversation conv;
private MessagePayload payload;
private List<String> toUsers;
public String getSender() {
return sender;
@@ -41,6 +44,14 @@ public class SendMessageData {
this.payload = payload;
}
public List<String> getToUsers() {
return toUsers;
}
public void setToUsers(List<String> toUsers) {
this.toUsers = toUsers;
}
public static boolean isValide(SendMessageData sendMessageData) {
if(sendMessageData == null ||
sendMessageData.getConv() == null ||
@@ -55,10 +66,18 @@ public class SendMessageData {
}
public WFCMessage.Message toProtoMessage() {
return WFCMessage.Message.newBuilder().setFromUser(sender)
.setConversation(WFCMessage.Conversation.newBuilder().setType(conv.getType()).setTarget(conv.getTarget()).setLine(conv.getLine()))
.setContent(payload.toProtoMessageContent())
.build();
if (toUsers != null && toUsers.size() > 0) {
return WFCMessage.Message.newBuilder().setFromUser(sender)
.setConversation(WFCMessage.Conversation.newBuilder().setType(conv.getType()).setTarget(conv.getTarget()).setLine(conv.getLine()))
.setContent(payload.toProtoMessageContent())
.addAllTo(toUsers)
.build();
} else {
return WFCMessage.Message.newBuilder().setFromUser(sender)
.setConversation(WFCMessage.Conversation.newBuilder().setType(conv.getType()).setTarget(conv.getTarget()).setLine(conv.getLine()))
.setContent(payload.toProtoMessageContent())
.build();
}
}
public static SendMessageData fromProtoMessage(WFCMessage.Message protoMessage) {
@@ -28,8 +28,8 @@ log4j.logger.io.moquette.parser.netty=WARN
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.Threshold=INFO
log4j.appender.file.File=logs/wildfirechat.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=20
log4j.appender.file.MaxFileSize=20MB
log4j.appender.file.MaxBackupIndex=100
log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%-4r [%t] %-5p %c{1} %x - %m%n
log4j.appender.file.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss,SSS} [%t] %-5p %c{1} %L %x - %m%n
@@ -41,7 +41,7 @@ log4j.appender.messagelog=org.apache.log4j.RollingFileAppender
log4j.appender.messagelog.Threshold=WARN
log4j.appender.messagelog.File=logs/wildfirechat_messages.log
log4j.appender.messagelog.MaxFileSize=100MB
log4j.appender.messagelog.MaxBackupIndex=1
log4j.appender.messagelog.MaxBackupIndex=3
log4j.appender.messagelog.layout=org.apache.log4j.PatternLayout
log4j.appender.messagelog.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss,SSS} [%t] %-5p %c{1} %L %x - %m%n
@@ -64,6 +64,9 @@ friend.repeat_request_duration 604800000
##好友请求被拒绝后再次发送的间隔,单位是毫秒,默认是30天,0为不限制
friend.reject_request_duration 2592000000
##好友请求过期时间,单位是毫秒,默认是7天,0为不限制
friend.request_expiration_duration 604800000
## 聊天室观众空闲退出时间,单位为毫秒,默认为15分钟,0为永远不退出
chatroom.participant_idle_time 900000
@@ -6,8 +6,15 @@ import cn.wildfirechat.sdk.model.IMResult;
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
public class ChatroomAdmin {
public static IMResult<OutputCreateChatroom> createChatroom(InputCreateChatroom input) throws Exception {
public static IMResult<OutputCreateChatroom> createChatroom(String chatroomId, String title, String desc ,String portrait, String extra, Integer state) throws Exception {
String path = APIPath.Create_Chatroom;
InputCreateChatroom input = new InputCreateChatroom();
input.setChatroomId(chatroomId);
input.setTitle(title);
input.setDesc(desc);
input.setPortrait(portrait);
input.setExtra(extra);
input.setState(state);
return AdminHttpUtils.httpJsonPost(path, input, OutputCreateChatroom.class);
}
@@ -469,6 +469,55 @@ public class Main {
System.out.println("destroy user failure");
System.exit(-1);
}
String chatroomId = "chatroomId1";
String chatroomTitle = "TESTCHATROM";
String chatroomDesc = "this is a test chatroom";
String chatroomPortrait = "http://pic.com/test123.png";
String chatroomExtra = "{\'managers:[\"user1\",\"user2\"]}";
IMResult<OutputCreateChatroom> chatroomIMResult = ChatroomAdmin.createChatroom(chatroomId,chatroomTitle, chatroomDesc, chatroomPortrait,chatroomExtra,ProtoConstants.ChatroomState.Chatroom_State_Normal);
if (chatroomIMResult != null && chatroomIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && chatroomIMResult.getResult().getChatroomId().equals(chatroomId)) {
System.out.println("create chatroom success");
} else {
System.out.println("create chatroom failure");
System.exit(-1);
}
IMResult<OutputGetChatroomInfo> getChatroomInfoIMResult = ChatroomAdmin.getChatroomInfo(chatroomId);
if (getChatroomInfoIMResult != null && getChatroomInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
if (!getChatroomInfoIMResult.getResult().getChatroomId().equals(chatroomId)
|| !getChatroomInfoIMResult.getResult().getTitle().equals(chatroomTitle)
|| !getChatroomInfoIMResult.getResult().getDesc().equals(chatroomDesc)
|| !getChatroomInfoIMResult.getResult().getPortrait().equals(chatroomPortrait)
|| !getChatroomInfoIMResult.getResult().getExtra().equals(chatroomExtra)
|| getChatroomInfoIMResult.getResult().getState() != ProtoConstants.ChatroomState.Chatroom_State_Normal) {
System.out.println("chatroom info incorrect");
System.exit(-1);
} else {
System.out.println("chatroom info incorrect");
}
} else {
System.out.println("get chatroom info failure");
System.exit(-1);
}
voidIMResult = ChatroomAdmin.destroyChatroom(chatroomId);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("destroy chatroom done!");
} else {
System.out.println("destroy chatroom failure");
System.exit(-1);
}
getChatroomInfoIMResult = ChatroomAdmin.getChatroomInfo(chatroomId);
if (getChatroomInfoIMResult != null && getChatroomInfoIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && getChatroomInfoIMResult.getResult().getState() == ProtoConstants.ChatroomState.Chatroom_State_End) {
System.out.println("chatroom destroyed!");
} else {
System.out.println("chatroom not destroyed!");
System.exit(-1);
}
System.out.println("Congratulation, all admin test case passed!!!!!!!");
}
static void testRobot() throws Exception {
@@ -67,31 +67,33 @@ public class AdminHttpUtils {
HttpResponse response = httpClient.execute(post);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode != HttpStatus.SC_OK){
LOG.info("Request error: "+statusCode);
throw new Exception("Http request error with code:" + statusCode);
}else{
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent(),"utf-8"));
StringBuffer sb = new StringBuffer();
String content = null;
if (response.getEntity().getContentLength() > 0) {
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
StringBuilder sb = new StringBuilder();
String line;
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
sb.append(line).append(NL);
}
in.close();
String content = sb.toString();
content = sb.toString();
LOG.info("http request response content: {}", content);
}
if(statusCode != HttpStatus.SC_OK){
LOG.info("Request error: " + statusCode + " error msg:" + content);
throw new Exception("Http request error with code:" + statusCode);
} else {
return fromJsonObject(content, clazz);
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}finally{
if(post != null){
} finally {
if(post != null) {
post.releaseConnection();
}
}