Compare commits

...
23 Commits
Author SHA1 Message Date
heavyrian2012 acb4cf81de version 0.83 2022-01-29 14:03:11 +08:00
heavyrian2012 ace676d215 修改接受好友后通知其他端的问题 2022-01-29 13:47:34 +08:00
heavyrian2012 1170c4209b fix test code 2022-01-29 11:47:19 +08:00
heavyrian2012 57e8814d9c 同步专业版代码 2022-01-29 11:43:44 +08:00
heavyrian2012 e3d9e0d183 处理好友请求后通知客户端更新好友请求信息 2022-01-26 21:53:35 +08:00
heavyrian2012 d6f5614f49 version 0.82 2022-01-26 13:45:29 +08:00
heavyrian2012 9ed4ab7e08 同步专业版SDK 2022-01-17 19:33:32 +08:00
heavyrian2012 4da3d3421d sdk中添加更新消息的接口 2022-01-13 20:57:02 +08:00
heavyrain2012 40ef9abd35 销毁用户时,清理干净所有信息 2022-01-08 16:36:18 +08:00
heavyrian2012 6f5b021c89 解决在线逻辑错误问题 2022-01-06 09:56:46 +08:00
heavyrian2012 f8f225d741 version 0.81 2022-01-05 14:31:37 +08:00
imndx 546110f6d3 修复存储用户消息错误问题 2022-01-05 11:26:40 +08:00
heavyrain2012 c7dbf45af6 当关闭pc在线通知时可以清理掉历史在线状态 2021-12-30 16:47:00 +08:00
heavyrain2012 1434dafd36 version 0.80 2021-12-29 21:03:34 +08:00
heavyrain2012 0d8a6e64ea log4j 2.17.1 2021-12-29 15:09:10 +08:00
heavyrain2012 d96c201aec add log 2021-12-28 19:30:48 +08:00
heavyrain2012 d901707691 add log 2021-12-28 19:22:55 +08:00
heavyrain2012 f456a4cc65 修正在线状态错误问题 2021-12-26 14:52:23 +08:00
heavyrain2012 c4bd706272 support pad platform 2021-12-26 13:47:01 +08:00
heavyrain2012 503768c04b 获取群组成员信息带上创建时间 2021-12-24 22:19:02 +08:00
heavyrain2012 7ca3abe12d 频道权限问题,非订阅用户可以给全局频道和可以给非订阅用户发消息的频道回复消息 2021-12-24 22:14:04 +08:00
heavyrain2012 cb09026408 添加注释 2021-12-24 22:02:40 +08:00
heavyrain2012 fab381a351 add log 2021-12-24 11:25:47 +08:00
36 changed files with 332 additions and 70 deletions
+2 -1
View File
@@ -32,7 +32,8 @@ host 0.0.0.0
##本地绑定端口
local_port 80
##是否使用内置DB。0使用mysql;1使用h2db。
## 是否使用内置DB。0使用mysql;1使用h2db。
## MySQL需要把事物隔离级别改成"Read committed",使用命令来修改"set global transaction_isolation='read-committed';",其他数据库默认已经是这个级别不用修改
embed.db 1
## 是否自动清理历史消息记录,当为true时,IM服务会定时扫描t_messages_x和t_user_messages_x表,清除掉3年前的历史消息。
+4 -4
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.79</version>
<version>0.83</version>
</parent>
<artifactId>moquette-broker</artifactId>
@@ -27,18 +27,18 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.0</version>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.0</version>
<version>2.17.1</version>
</dependency>
<!--用于与slf4j保持桥接-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.0</version>
<version>2.17.1</version>
</dependency>
<!-- slf4j核心包-->
<dependency>
@@ -63,6 +63,7 @@ public class GetGroupMembersAction extends AdminAction {
pm.setAlias(member.getAlias());
pm.setType(member.getType());
pm.setExtra(member.getExtra());
pm.setCreateDt(member.getCreateDt());
out.getMembers().add(pm);
}
result = RestResult.ok(out);
@@ -70,6 +70,7 @@ abstract public class ChannelAction extends Action {
try {
ts = Long.parseLong(timestamp);
} catch (Exception e) {
LOG.error("Channel timestamp:{} invalid", timestamp);
e.printStackTrace();
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.CHANNEL_API_Exception);
return ErrorCode.ERROR_CODE_API_NOT_SIGNED;
@@ -81,7 +82,7 @@ abstract public class ChannelAction extends Action {
channelInfo = messagesStore.getChannelInfo(cid);
if (channelInfo == null) {
return ErrorCode.INVALID_PARAMETER;
return ErrorCode.ERROR_CODE_CHANNEL_NO_EXIST;
}
if (StringUtil.isNullOrEmpty(channelInfo.getSecret())) {
@@ -14,16 +14,12 @@ import cn.wildfirechat.pojos.InputGetUserInfo;
import cn.wildfirechat.pojos.InputOutputUserInfo;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.admin.AdminAction;
import com.xiaoleilu.loServer.action.robot.RobotAction;
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.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
@Route(APIPath.Channel_User_Info)
@@ -12,7 +12,6 @@ package com.xiaoleilu.loServer.action.channel;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.pojos.SendChannelMessageData;
import cn.wildfirechat.proto.ProtoConstants;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
@@ -24,7 +23,6 @@ import cn.wildfirechat.pojos.SendMessageResult;
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 cn.wildfirechat.common.ErrorCode;
import win.liyufan.im.IMTopic;
@@ -67,6 +67,7 @@ public class GetGroupMembersAction extends RobotAction {
pm.setAlias(member.getAlias());
pm.setType(member.getType());
pm.setExtra(member.getExtra());
pm.setCreateDt(member.getCreateDt());
out.getMembers().add(pm);
}
if(!isInGroup) {
@@ -28,7 +28,7 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.HandleFriendRequest request, Qos1PublishHandler.IMCallback callback) {
WFCMessage.Message.Builder builder = WFCMessage.Message.newBuilder();
builder.setFromUser(request.getTargetUid());
long[] heads = new long[2];
long[] heads = new long[4];
boolean isAdmin = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Admin;
ErrorCode errorCode = m_messagesStore.handleFriendRequest(fromUser, request, builder, heads, isAdmin);
@@ -84,6 +84,14 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
publisher.publishNotification(IMTopic.NotifyFriendTopic, request.getTargetUid(), heads[0]);
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[1]);
}
if(!isAdmin) {
if(heads[2] > 0) {
publisher.publishNotification(IMTopic.NotifyFriendRequestTopic, request.getTargetUid(), heads[2], fromUser, null);
}
if(heads[3] > 0) {
publisher.publishNotification(IMTopic.NotifyFriendRequestTopic, fromUser, heads[3], fromUser, null);
}
}
}
if(errorCode == ERROR_CODE_ALREADY_FRIENDS) {
errorCode = ERROR_CODE_SUCCESS;
@@ -33,7 +33,7 @@ public class LoadRemoteMessagesHandler extends IMHandler<WFCMessage.LoadRemoteMe
}
if (request.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
if (!m_messagesStore.checkUserInChannel(fromUser, request.getConversation().getTarget())) {
if (!m_messagesStore.canSendMessageInChannel(fromUser, request.getConversation().getTarget())) {
return ErrorCode.ERROR_CODE_NOT_IN_CHANNEL;
}
}
@@ -32,6 +32,11 @@ public class RouteHandler extends IMHandler<WFCMessage.RouteRequest> {
}
if (session == null || session.getDeleted() > 0) {
if(session == null) {
LOG.error("Session for <{}, {}> not exist", fromUser, clientID);
} else {
LOG.error("Session for <{}, {}> deleted", fromUser, clientID);
}
return ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH;
}
@@ -154,7 +154,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
}
} else if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
if(!m_messagesStore.getGroupMuteExceptionTypes().contains(message.getContent().getType())) {
if (!m_messagesStore.checkUserInChannel(fromUser, message.getConversation().getTarget())) {
if (!m_messagesStore.canSendMessageInChannel(fromUser, message.getConversation().getTarget())) {
return ErrorCode.ERROR_CODE_NOT_IN_CHANNEL;
}
}
@@ -914,20 +914,24 @@ public class DatabaseStore {
return false;
}
void persistUserMessage(final String userId, final long messageId, final long messageSeq, final int messageContentType) {
void persistUserMessage(final String userId, final long messageId, final long messageSeq, int type, String target, int line, boolean directing, final int messageContentType) {
mScheduler.execute(()->{
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
String sql = "insert into " + getUserMessageTable(userId) + " (`_mid`, `_uid`, `_seq`, `_cont_type`) values(?, ?, ?, ?)";
String sql = "insert into " + getUserMessageTable(userId) + " (`_mid`, `_uid`, `_seq`, `_type`, `_target`, `_line`, `_directing`, `_cont_type`) values(?, ?, ?, ?, ?, ?, ?, ?)";
statement = connection.prepareStatement(sql);
int index = 1;
statement.setLong(index++, messageId);
statement.setString(index++, userId);
statement.setLong(index++, messageSeq);
statement.setInt(index++, type);
statement.setString(index++, target);
statement.setInt(index++, line);
statement.setInt(index++, directing ? 1 :0);
statement.setInt(index++, messageContentType);
int count = statement.executeUpdate();
LOG.info("Update rows {}", count);
@@ -48,7 +48,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
import static cn.wildfirechat.proto.ProtoConstants.ChannelState.Channel_State_Mask_Deleted;
import static cn.wildfirechat.proto.ProtoConstants.ChannelState.*;
import static cn.wildfirechat.proto.ProtoConstants.ChannelUpdateEventType.*;
import static cn.wildfirechat.proto.ProtoConstants.ChatroomMemberUpdateEventType.Chatroom_Member_Event_Join;
import static cn.wildfirechat.proto.ProtoConstants.ChatroomMemberUpdateEventType.Chatroom_Member_Event_Leave;
@@ -866,7 +866,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
@Override
public long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String user, long messageId) {
public long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String user, long messageId, boolean directing) {
// messageId是全局的,messageSeq是跟个人相关的,理论上messageId的增长数度远远大于seq。
// 考虑到一种情况,当服务器发生变化,用户发生迁移后,messageSeq还需要保持有序。 要么把Seq持久化,要么在迁移后Seq取一个肯定比以前更大的数字(这个数字就是messageId)
// 这里选择使用后面一种情况
@@ -906,7 +906,7 @@ public class MemoryMessagesStore implements IMessagesStore {
mWriteLock.unlock();
}
databaseStore.persistUserMessage(user, messageId, messageSeq, messageContentType);
databaseStore.persistUserMessage(user, messageId, messageSeq, conversationType, target, line, directing, messageContentType);
return messageSeq;
}
@@ -2313,6 +2313,24 @@ public class MemoryMessagesStore implements IMessagesStore {
}
public void forceCleanOnlineStatus(String userId, String clientId) {
if (m_Server.isShutdowning()) {
return;
}
if(!mMultiPlatformNotification || m_Server.getStore().sessionsStore().isMultiEndpointSupported()) {
WFCMessage.UserSettingEntry pcentry = getUserSetting(userId, kUserSettingPCOnline, "PC");
if (pcentry != null && !StringUtil.isNullOrEmpty(pcentry.getValue()) && pcentry.getValue().contains(clientId)) {
updateUserSettings(userId, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue("").build(), clientId);
}
WFCMessage.UserSettingEntry padentry = getUserSetting(userId, kUserSettingPCOnline, "Pad");
if (padentry != null && !StringUtil.isNullOrEmpty(padentry.getValue()) && padentry.getValue().contains(clientId)) {
updateUserSettings(userId, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("Pad").setValue("").build(), clientId);
}
}
}
@Override
public void updateUserOnlineSetting(MemorySessionStore.Session session, boolean online) {
if(!mMultiPlatformNotification) {
@@ -2326,39 +2344,31 @@ public class MemoryMessagesStore implements IMessagesStore {
return;
}
if (session.getPlatform() == Platform_LINUX || session.getPlatform() == Platform_Windows || session.getPlatform() == Platform_OSX) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue(online ? (System.currentTimeMillis() + "|" + session.getPlatform() + "|" + session.getClientID() + "|" + session.getPhoneName()) : "").build(), session.clientID);
} else {
String value = null;
for (MemorySessionStore.Session s : m_Server.getStore().sessionsStore().sessionForUser(session.username)) {
if (s.getDeleted() != 0 || !m_Server.getConnectionsManager().isConnected(s.getClientID())) {
continue;
}
switch (s.getPlatform()) {
case Platform_LINUX:
case Platform_Windows:
case Platform_OSX:
value = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
break;
default:
break;
}
if (value != null) {
break;
}
String pcValue = null;
for (MemorySessionStore.Session s : m_Server.getStore().sessionsStore().sessionForUser(session.username)) {
if (s.getDeleted() != 0 || !m_Server.getConnectionsManager().isConnected(s.getClientID())) {
continue;
}
WFCMessage.UserSettingEntry pcentry = getUserSetting(session.getUsername(), kUserSettingPCOnline, "PC");
if (value != null) {
if (pcentry == null || StringUtil.isNullOrEmpty(pcentry.getValue())) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue(value).build(), session.clientID);
}
} else {
if (pcentry != null && !StringUtil.isNullOrEmpty(pcentry.getValue())) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue("").build(), session.clientID);
}
switch (s.getPlatform()) {
case Platform_LINUX:
case Platform_Windows:
case Platform_OSX:
pcValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
break;
default:
break;
}
}
WFCMessage.UserSettingEntry pcentry = getUserSetting(session.getUsername(), kUserSettingPCOnline, "PC");
if (pcValue != null) {
if (pcentry == null || StringUtil.isNullOrEmpty(pcentry.getValue())) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue(pcValue).build(), session.clientID);
}
} else {
if (pcentry != null && !StringUtil.isNullOrEmpty(pcentry.getValue())) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue("").build(), session.clientID);
}
}
}
@@ -2478,7 +2488,21 @@ 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())
.setName(userId)
.setDeleted(1)
.clearDisplayName()
.clearAddress()
.clearCompany()
.clearEmail()
.clearExtra()
.clearMobile()
.clearPortrait()
.clearSocial()
.build();
try {
databaseStore.updateUser(us);
} catch (Exception e) {
@@ -3009,6 +3033,8 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_FRIEND_REQUEST_EXPIRED;
} else {
existRequest = existRequest.toBuilder().setStatus(request.getStatus()).setUpdateDt(System.currentTimeMillis()).build();
heads[2] = existRequest.getUpdateDt();
heads[3] = existRequest.getUpdateDt();
databaseStore.persistOrUpdateFriendRequest(existRequest);
if (request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted) {
@@ -3751,6 +3777,34 @@ public class MemoryMessagesStore implements IMessagesStore {
return mIMap.get(channelId);
}
@Override
public boolean canSendMessageInChannel(String user, String channelId) {
IMap<String, WFCMessage.ChannelInfo> mIMap = m_Server.getHazelcastInstance().getMap(CHANNELS);
WFCMessage.ChannelInfo info = mIMap.get(channelId);
if(info == null || info.getStatus() == Channel_State_Mask_Deleted) {
return false;
}
if(user.equals(info.getOwner())) {
return true;
}
if((info.getStatus() & Channel_State_Mask_Global) > 0 || (info.getStatus() & Channel_State_Mask_Message_Unsubscribed) > 0) {
return true;
}
Collection<String> channelMembers = getChannelListener(channelId);
if (channelMembers == null) {
return false;
}
Collection<String> chatroomMembers = getChannelListener(channelId);
if (chatroomMembers == null || !chatroomMembers.contains(user)) {
return false;
}
return true;
}
@Override
public boolean checkUserInChannel(String user, String channelId) {
Collection<String> channelMembers = getChannelListener(channelId);
@@ -723,6 +723,11 @@ public class MemorySessionStore implements ISessionsStore {
public ErrorCode kickoffPCClient(String operator, String pcClientId) {
Session session = sessions.get(pcClientId);
if (session != null) {
if(!operator.equals(session.getUsername())) {
LOG.error("kickoffPCClient failure, user {} don't have client {}", operator, pcClientId);
mServer.getProcessor().getMessagesStore().forceCleanOnlineStatus(operator, pcClientId);
return ErrorCode.ERROR_CODE_SUCCESS;
}
if (session.getPlatform() == ProtoConstants.Platform.Platform_LINUX
|| session.getPlatform() == ProtoConstants.Platform.Platform_WEB
|| session.getPlatform() == ProtoConstants.Platform.Platform_Windows
@@ -731,8 +736,12 @@ public class MemorySessionStore implements ISessionsStore {
sessions.remove(pcClientId);
mServer.getProcessor().kickoffSession(session);
} else {
LOG.error("session {} is not pc client:{}", pcClientId, session.getPlatform());
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
} else {
LOG.error("Can't find the session for client <{}>", pcClientId);
mServer.getProcessor().getMessagesStore().forceCleanOnlineStatus(operator, pcClientId);
}
return ErrorCode.ERROR_CODE_SUCCESS;
}
@@ -106,7 +106,7 @@ public interface IMessagesStore {
Set<String> getAllEnds();
WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType);
WFCMessage.PullMessageResult loadRemoteMessages(String user, WFCMessage.Conversation conversation, long beforeUid, int count, Collection<Integer> contentTypes);
long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String userId, long messageId);
long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String userId, long messageId, boolean directing);
WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin);
ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra);
ErrorCode kickoffGroupMembers(String operator, boolean isAdmin, String groupId, List<String> memberList);
@@ -140,6 +140,8 @@ public interface IMessagesStore {
ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request) throws Exception;
void forceCleanOnlineStatus(String userId, String clientId);
void updateUserOnlineSetting(MemorySessionStore.Session session, boolean online);
ErrorCode modifyUserStatus(String userId, int status);
@@ -211,6 +213,7 @@ public interface IMessagesStore {
List<WFCMessage.ChannelInfo> searchChannel(String keyword, boolean buzzy, int page);
ErrorCode listenChannel(String operator, String channelId, boolean listen);
WFCMessage.ChannelInfo getChannelInfo(String channelId);
boolean canSendMessageInChannel(String user, String channelId);
boolean checkUserInChannel(String user, String channelId);
Collection<String> getChannelSubscriber(String channelId);
@@ -160,7 +160,7 @@ public class MessagesPublisher {
}
}
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) {
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, boolean directing) {
if (persistFlag == Transparent) {
publishTransparentMessage2Receivers(messageId, receivers, pullType, exceptClientId);
return;
@@ -191,7 +191,7 @@ public class MessagesPublisher {
}
long messageSeq;
if (pullType != ProtoConstants.PullType.Pull_ChatRoom) {
messageSeq = m_messagesStore.insertUserMessages(sender, conversationType, target, line, messageContentType, user, messageId);
messageSeq = m_messagesStore.insertUserMessages(sender, conversationType, target, line, messageContentType, user, messageId, directing);
} else {
messageSeq = m_messagesStore.insertChatroomMessages(user, line, messageId);
}
@@ -644,7 +644,7 @@ public class MessagesPublisher {
message.getConversation().getType(), message.getConversation().getTarget(), message.getConversation().getLine(),
messageId,
receivers,
pushContent, message.getContent().getPushData(), exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag());
pushContent, message.getContent().getPushData(), exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag(), message.hasToUser() || !message.getToList().isEmpty());
}
@@ -622,14 +622,15 @@ public class ProtocolProcessor {
if(session != null) {
session.refreshLastActiveTime();
forwardOnlineStatusEvent(username, clientID, session.getPlatform(), clearSession ? UserOnlineStatus.LOGOUT : UserOnlineStatus.OFFLINE, session.getAppName());
m_messagesStore.updateUserOnlineSetting(session, false);
}
ConnectionDescriptor oldConnDescr = new ConnectionDescriptor(clientID, channel);
if(connectionDescriptors.removeConnection(oldConnDescr)) {
m_interceptor.notifyClientConnectionLost(clientID, username);
}
if(session != null) {
m_messagesStore.updateUserOnlineSetting(session, false);
}
}
/**
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.79</version>
<version>0.83</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -32,6 +32,8 @@ public interface APIPath {
String User_Put_Setting = "/admin/user/put_setting";
String User_Get_Setting = "/admin/user/get_setting";
String User_Kickoff_Client = "/admin/user/kickoff_client";
String User_Online_Count = "/admin/user/online_count";
String User_Online_List = "/admin/user/online_list";
String Friend_Update_Status = "/admin/friend/status";
String Friend_Get_List = "/admin/friend/list";
@@ -47,6 +49,7 @@ public interface APIPath {
String Msg_Send = "/admin/message/send";
String Msg_Recall = "/admin/message/recall";
String Msg_Delete = "/admin/message/delete";
String Msg_Update = "/admin/message/update";
String Msg_Broadcast = "/admin/message/broadcast";
String Msg_Multicast = "/admin/message/multicast";
String Msg_RecallBroadCast = "/admin/message/recall_broadcast";
@@ -49,6 +49,7 @@ public enum ErrorCode {
ERROR_CODE_WS_NOT_CONFIGURED_CORRECTLY(28, "ws not configured correctly"),
ERROR_CODE_CONFERENCE_ROOM_NOT_EXIST(60, "conference room not exist"),
ERROR_CODE_CHANNEL_NO_EXIST(236, "channel no exist"),
ERROR_CODE_CHANNEL_NO_SECRET(237, "channel no secret"),
ERROR_CODE_USER_NOT_PREPARED(238, "user not prepared"),
ERROR_CODE_API_NOT_SIGNED(239, "api not signed or sign parameter not completion"),
@@ -0,0 +1,10 @@
package cn.wildfirechat.pojos;
import java.util.ArrayList;
public class GetOnlineUserCountResult extends ArrayList<GetOnlineUserCountResult.Node> {
public static class Node {
public int node;
public int count;
}
}
@@ -0,0 +1,9 @@
package cn.wildfirechat.pojos;
import java.util.ArrayList;
public class GetOnlineUserRequest {
public int nodeId;
public int offset;
public int count;
}
@@ -0,0 +1,15 @@
package cn.wildfirechat.pojos;
import java.util.ArrayList;
public class GetOnlineUserResult {
public static class UserClient {
public String userId;
public String clientId;
public int platform;
}
ArrayList<GetOnlineUserResult.UserClient> userClients;
public int totalCount;
public int offset;
}
@@ -19,12 +19,11 @@ public class OutputGetChannelInfo {
private String extra;
private String owner;
private int state;
//此字段已经废弃,为了兼容旧的SDK版本,以后会移除
@Deprecated()
private int status;
private long updateDt;
private String callback;
private int automatic;
private String secret;
public String getChannelId() {
@@ -115,6 +114,14 @@ public class OutputGetChannelInfo {
this.status = status;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public static OutputGetChannelInfo fromPbInfo(WFCMessage.ChannelInfo channelInfo) {
OutputGetChannelInfo out = new OutputGetChannelInfo();
out.automatic = channelInfo.getAutomatic();
@@ -126,8 +133,9 @@ public class OutputGetChannelInfo {
out.owner = channelInfo.getOwner();
out.portrait = channelInfo.getPortrait();
out.state = channelInfo.getStatus();
out.status = out.state;
out.status = channelInfo.getStatus();;
out.updateDt = channelInfo.getUpdateDt();
out.secret = channelInfo.getSecret();
return out;
}
}
@@ -8,4 +8,5 @@ public class PojoConferenceCreate {
public int bitrate;
public boolean advance;
public boolean recording;
public boolean permanent;
}
@@ -13,6 +13,7 @@ public class PojoGroupMember {
String alias;
int type;
String extra;
long createDt;
public String getMember_id() {
return member_id;
@@ -45,4 +46,12 @@ public class PojoGroupMember {
public void setExtra(String extra) {
this.extra = extra;
}
public long getCreateDt() {
return createDt;
}
public void setCreateDt(long createDt) {
this.createDt = createDt;
}
}
@@ -0,0 +1,57 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class UpdateMessageContentData {
private String operator;
private long messageUid;
private MessagePayload payload;
private int distribute;
private int updateTimestamp;
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public long getMessageUid() {
return messageUid;
}
public void setMessageUid(long messageUid) {
this.messageUid = messageUid;
}
public MessagePayload getPayload() {
return payload;
}
public void setPayload(MessagePayload payload) {
this.payload = payload;
}
public int getDistribute() {
return distribute;
}
public void setDistribute(int distribute) {
this.distribute = distribute;
}
public int getUpdateTimestamp() {
return updateTimestamp;
}
public void setUpdateTimestamp(int updateTimestamp) {
this.updateTimestamp = updateTimestamp;
}
}
@@ -48,6 +48,8 @@ public class ProtoConstants {
int Platform_WEB = 5;
int Platform_WX = 6;
int Platform_LINUX = 7;
int Platform_iPad = 8;
int Platform_APad = 9;
}
//message NotifyMessage & PullMessageRequest -> type
@@ -127,7 +129,7 @@ public class ProtoConstants {
//第3位表示是否允许给非订阅用户发送消息
//第4位表示是否私有,不可以被用户搜索和主动订阅
//第6位表示是否删除
//第8位表示是否是全局频道,全局频道没有订阅关系,会发送给系统内所有成员。
//第8位表示是否是全局频道,全局频道没有订阅关系,会发送给系统内所有成员。可以给非订阅用户单独发消息。
public interface ChannelState {
int Channel_State_Mask_FullInfo = 0x01;
int Channel_State_Mask_Unsubscribed_User_Access = 0x02;
+1 -1
View File
@@ -6,7 +6,7 @@
<!--<relativePath>../pom.xml</relativePath>-->
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.79</version>
<version>0.83</version>
</parent>
<artifactId>distribution</artifactId>
@@ -28,7 +28,8 @@ host 0.0.0.0
##本地绑定端口
local_port 80
##是否使用内置DB。0使用mysql;1使用h2db。
## 是否使用内置DB。0使用mysql;1使用h2db。
## MySQL需要把事物隔离级别改成"Read committed",使用命令来修改"set global transaction_isolation='read-committed';",其他数据库默认已经是这个级别不用修改
embed.db 1
## 是否自动清理历史消息记录,当为true时,IM服务会定时扫描t_messages_x和t_user_messages_x表,清除掉3年前的历史消息。
+1 -1
View File
@@ -12,7 +12,7 @@
<artifactId>wildfirechat-parent</artifactId>
<packaging>pom</packaging>
<version>0.79</version>
<version>0.83</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.79</version>
<version>0.83</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -17,7 +17,7 @@ public class ConferenceAdmin {
return AdminHttpUtils.httpJsonPost(path, data, PojoConferenceParticipantList.class);
}
public static IMResult<Void> createRoom(String roomId, String description, String pin, int maxPublisher, boolean advance, int bitrate, boolean recording) throws Exception {
public static IMResult<Void> createRoom(String roomId, String description, String pin, int maxPublisher, boolean advance, int bitrate, boolean recording, boolean permanent) throws Exception {
String path = APIPath.Conference_Create;
PojoConferenceCreate create = new PojoConferenceCreate();
create.roomId = roomId;
@@ -27,6 +27,7 @@ public class ConferenceAdmin {
create.advance = advance;
create.bitrate = bitrate;
create.recording = recording;
create.permanent = permanent;
return AdminHttpUtils.httpJsonPost(path, create, Void.class);
}
@@ -20,6 +20,7 @@ import static cn.wildfirechat.proto.ProtoConstants.SystemSettingType.Group_Max_M
public class Main {
private static boolean commercialServer = false;
private static boolean advanceVoip = false;
//管理端口是8080
private static String AdminUrl = "http://localhost:18080";
private static String AdminSecret = "123456";
@@ -51,6 +52,8 @@ public class Main {
testSensitiveApi();
if (commercialServer) {
testDevice();
}
if(advanceVoip) {
testConference();
}
@@ -269,6 +272,24 @@ public class Main {
System.out.println("destroy user failure");
System.exit(-1);
}
if (commercialServer) {
IMResult<GetOnlineUserCountResult> getOnlineUserCountResultIMResult = UserAdmin.getOnlineUserCount();
if (getOnlineUserCountResultIMResult != null && getOnlineUserCountResultIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("get user online count success");
} else {
System.out.println("get user online count failure");
System.exit(-1);
}
IMResult<GetOnlineUserResult> getOnlineUserResultIMResult = UserAdmin.getOnlineUser(1, 0, 100);
if (getOnlineUserResultIMResult != null && getOnlineUserResultIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("get user online success");
} else {
System.out.println("get user online failure");
System.exit(-1);
}
}
}
//***********************************************
@@ -664,6 +685,24 @@ public class Main {
System.exit(-1);
}
payload.setSearchableContent("hello world2");
resultSendMessage = MessageAdmin.sendMessage("user1", conversation, payload, null);
if (resultSendMessage != null && resultSendMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("send message success");
} else {
System.out.println("send message failure");
System.exit(-1);
}
payload.setSearchableContent("hello world3");
voidIMResult = MessageAdmin.updateMessageContent("user1", resultSendMessage.getResult().getMessageUid(), payload, true);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("update message success");
} else {
System.out.println("update message failure");
System.exit(-1);
}
IMResult<BroadMessageResult> resultBroadcastMessage = MessageAdmin.broadcastMessage("user1", 0, payload);
if (resultBroadcastMessage != null && resultBroadcastMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("broad message success, send message to " + resultBroadcastMessage.getResult().getCount() + " users");
@@ -821,6 +860,7 @@ public class Main {
System.exit(-1);
}
Thread.sleep(1000);
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!");
@@ -1486,7 +1526,7 @@ public class Main {
System.out.println("conference list " + listResult.getResult().conferenceInfoList);
}
IMResult<Void> createResult = ConferenceAdmin.createRoom("helloroomid", "hello room description", "123456", 9, false, 0, false);
IMResult<Void> createResult = ConferenceAdmin.createRoom("helloroomid", "hello room description", "123456", 9, false, 0, false, true);
if(createResult == null || createResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("create conference failure");
System.exit(-1);
@@ -1494,7 +1534,7 @@ public class Main {
System.out.println("create conference");
}
createResult = ConferenceAdmin.createRoom("helloroomid2", "hello room description advanced", "123456", 20, true, 0, false);
createResult = ConferenceAdmin.createRoom("helloroomid2", "hello room description advanced", "123456", 20, true, 0, false, true);
if(createResult == null || createResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("create conference failure");
System.exit(-1);
@@ -37,6 +37,17 @@ public class MessageAdmin {
return AdminHttpUtils.httpJsonPost(path, deleteMessageData, Void.class);
}
public static IMResult<Void> updateMessageContent(String operator, long messageUid, MessagePayload payload, boolean distribute) throws Exception {
String path = APIPath.Msg_Update;
UpdateMessageContentData updateMessageContentData = new UpdateMessageContentData();
updateMessageContentData.setOperator(operator);
updateMessageContentData.setMessageUid(messageUid);
updateMessageContentData.setPayload(payload);
updateMessageContentData.setDistribute(distribute?1:0);
updateMessageContentData.setUpdateTimestamp(0);
return AdminHttpUtils.httpJsonPost(path, updateMessageContentData, Void.class);
}
/**
@@ -117,4 +117,16 @@ public class UserAdmin {
inputUserId.setUserId(userId);
return AdminHttpUtils.httpJsonPost(path, inputUserId, OutputDeviceList.class);
}
public static IMResult<GetOnlineUserCountResult> getOnlineUserCount() throws Exception {
return AdminHttpUtils.httpJsonPost(APIPath.User_Online_Count, null, GetOnlineUserCountResult.class);
}
public static IMResult<GetOnlineUserResult> getOnlineUser(int nodeId, int offset, int count) throws Exception {
GetOnlineUserRequest request = new GetOnlineUserRequest();
request.nodeId = nodeId;
request.offset = offset;
request.count = count;
return AdminHttpUtils.httpJsonPost(APIPath.User_Online_List, request, GetOnlineUserResult.class);
}
}