Compare commits

..
100 Commits
Author SHA1 Message Date
imhao183 a973a731e4 update version to 0.53 2021-02-13 20:54:33 +08:00
heavyrain2012 90449e08c6 解决某些特殊情况下,群组成员个数错误问题 2021-02-12 21:20:44 +08:00
heavyrain2012 5857a3fbd1 Revert "同步群成员状态,当群成员不存在时,返回删除状态"
This reverts commit ae4d8a95ba.
2021-02-12 18:01:55 +08:00
heavyrain2012 ae4d8a95ba 同步群成员状态,当群成员不存在时,返回删除状态 2021-02-12 17:58:27 +08:00
imhao183 9fa1370219 添加获取两个用户好友关系的接口 2021-02-09 14:58:07 +08:00
imhao183 dd4cdb4bc4 修正问题:创建群组时,如果没有把owner加入到群成员列表中,服务器自动加入群成员列表,但count计数时没有加入。 2021-02-01 16:02:43 +08:00
imhao183 e07b839671 修改允许客户端自定义群通知配置默认值为true 2021-01-30 21:45:45 +08:00
imhao183 3a0653b8ed 添加端口被占用时的提示说明 2021-01-30 09:17:57 +08:00
imhao183 b4979e5408 修正当敏感词策略为忽略时敏感词消息会从历史消息功能中拉取的问题 2021-01-30 09:09:25 +08:00
imhao183 59cb884772 update version to 0.52 2021-01-25 14:46:31 +08:00
imhao183 3d0a36b4f3 优化自动清理历史消息逻辑 2021-01-24 20:27:22 +08:00
heavyrain2012 7923a3e0c4 db 自动清除过期历史消息数据 2021-01-23 18:01:28 +08:00
imhao183 e5a4aa4741 内置存储下载带上contenttype 2021-01-23 17:01:12 +08:00
imhao183 e76e8b38df 解决特殊文件下报异常的问题 2021-01-23 15:58:53 +08:00
imhao183 5f7df37664 添加踢用户下线api接口 2021-01-22 10:23:33 +08:00
imhao183 2c9e8d66e8 优化踢客户端下线逻辑 2021-01-22 09:34:03 +08:00
imhao183 d7eddbf7b4 请求数据非法时给出错误响应码 2021-01-22 09:32:55 +08:00
imhao183 3b783fb72e push void answer 2021-01-21 20:51:08 +08:00
imhao183 4e9e87f113 docker file 2021-01-19 15:32:37 +08:00
imhao183 0f0b3398d7 禁止客户端直接修改电话号码,电话号码只能通过server api来修改 2021-01-16 10:30:41 +08:00
imhao183 a725b507c7 机器人api 2021-01-16 10:29:03 +08:00
imhao183 46423a341d 创建群组时,当owner没有加入到群成员列表中时,自动加入到群成员列表 2021-01-16 10:28:44 +08:00
heavyrain2012 f70ae457af add robot callback api 2021-01-16 09:13:53 +08:00
imhao183 29b30cec28 fix build error 2021-01-15 22:27:17 +08:00
imhao183 fc05973b5d 创建群组时使用类型2 2021-01-15 22:23:00 +08:00
imhao183 97a21ff201 添加机器人群组操作 2021-01-15 22:22:42 +08:00
imhao183 0b90f0c56c update sql script alter change status column 2021-01-15 22:21:24 +08:00
imhao183 07454aedce add robot create group function 2021-01-15 22:21:08 +08:00
imhao183 ee26284d39 update 2021-01-14 10:39:08 +08:00
imhao183 99e24dca1c 截取推送信息日志长度,防止消息内容打印到日志中去 2021-01-14 10:37:23 +08:00
imhao183 5dbfeaabf9 sdk添加对设置会话置顶的功能 2021-01-14 10:28:17 +08:00
imhao183 38595c06d8 添加注释 2021-01-13 20:16:27 +08:00
imhao183 e65e313ef3 添加配置,是否不同步指定用户信息到客户端 2021-01-11 12:40:39 +08:00
imhao183 4e5355af11 update version to 0.51 2021-01-08 21:20:37 +08:00
imhao183 fa47de1904 修改注释 2021-01-08 21:15:23 +08:00
imhao183 4abf1ed941 优化多端踢下线的逻辑 2021-01-08 09:45:52 +08:00
heavyrain2012 9b0ca7ac3c 解决某些特殊情况下用户session错误问题 2021-01-04 15:27:57 +08:00
imhao183 772940e50d 解决清除数据库后拉取历史消息时,无法获取自己发送消息问题 2020-12-31 20:14:23 +08:00
imhao183 c63cc74028 修正会话静音设置缓存错误问题 2020-12-26 16:18:56 +08:00
imhao183 76aff64a1b remove useless code 2020-12-24 12:50:23 +08:00
imhao183 9502b01b49 删除无效的配置及代码 2020-12-24 12:35:07 +08:00
heavyrain2012 5b476b205e update 2020-12-23 07:50:33 +08:00
heavyrain2012 d24d71d040 端口被占用时,打印出提醒日志 2020-12-20 15:30:37 +08:00
heavyrain2012 11b0e6454c 更新报警频率 2020-12-12 16:30:57 +08:00
heavyrain2012 31d69e78cf 异常报警功能 2020-12-12 16:27:15 +08:00
imhao183 28b732788c update 2020-12-11 12:34:32 +08:00
imhao183 2d1d5309bf 修改群昵称时发送群通知 2020-12-11 09:08:01 +08:00
imhao183 6d9eeb25d6 version 0.49->0.50 2020-12-10 18:28:27 +08:00
imhao183 32f63a7d9c 修改默认参数 2020-12-10 18:21:02 +08:00
imhao183 4d903ca379 1,添加设置群成员昵称api
2,配置当退群或者群踢人时,是否发送visible群通知
2020-12-10 18:03:41 +08:00
imhao183 d233dbdd99 添加禁止客户端发送某些类型配置功能 2020-12-02 15:38:16 +08:00
imhao183 0f32aa30ce 添加禁止客户端发送群通知开工 2020-12-02 15:32:46 +08:00
imndx 9e007185ba 解决sql语法错误. fix #305 2020-11-27 19:00:34 +08:00
imhao183 ab92bc116c update version to 0.49 2020-11-22 21:17:37 +08:00
imhao183 4308e51357 解决当用户关系不存在时,设置备注名失败的问题 2020-11-19 18:00:33 +08:00
imhao183 59977fb1ba 状态消息同步到发送者其它端时,排除掉发送端 2020-11-12 16:37:17 +08:00
imhao183 d912777974 fix file table name error 2020-11-12 10:28:32 +08:00
imhao183 19b7bc42ef fix build error 2020-11-11 18:34:43 +08:00
imhao183 e621bea8fa 添加撤回群发消息功能 2020-11-11 18:32:16 +08:00
imhao183 ca1cf03cc3 add recall multicast message request 2020-11-11 18:27:54 +08:00
imhao183 ed7e56ca75 add recall boardcast and multicast message api 2020-11-11 18:26:12 +08:00
heavyrain2012 40c5cd615d support java15 2020-11-11 16:29:59 +08:00
imhao183 3438de39ad 状态消息也需要同步到发送者的其它端 2020-11-11 13:08:28 +08:00
imhao183 7f6b2d93df toUsers参数没有带上及api兼容 2020-11-06 17:13:38 +08:00
imhao183 9c57a620c9 发送消息接口添加目标用户参数 2020-11-06 16:52:36 +08:00
imhao183 32252228b0 推送信息中带上用户Id 2020-11-06 16:44:44 +08:00
imhao183 396351cc15 update readme 2020-11-02 21:37:03 +08:00
imhao183 955c2182c8 update version to 0.48 2020-11-02 20:53:10 +08:00
heavyrain2012 823bd53da8 添加修正flyway migrate 38错误问题 2020-11-02 20:50:44 +08:00
heavyrain2012 e4588bfd9d 同步专业版数据库 2020-11-02 20:18:43 +08:00
imhao183 3b0f724ff0 update version to 0.47 2020-10-28 10:42:03 +08:00
imhao183 94bc595757 解决部分情况下消息id重复问题 2020-10-28 10:39:58 +08:00
imhao183 139042c8e7 添加免打扰功能及优化推送逻辑 2020-10-28 09:51:45 +08:00
imhao183 8e894e49b3 解决拉取历史消息问题 2020-10-23 11:24:44 +08:00
imhao183 c30a688032 remove useless fastjson 2020-10-22 10:37:12 +08:00
imhao183 06bcfea16e 拉取历史信息时,处理中间几个月时间没有消息的情况,最长间隔时24个月 2020-10-22 08:09:48 +08:00
imhao183 52bbf57760 Merge commit '30a62cfc58d12dc17406504873f1bc0e36f83a0d' into wildfirechat
* commit '30a62cfc58d12dc17406504873f1bc0e36f83a0d':
  Bump junit from 4.8.2 to 4.13.1 in /broker
2020-10-20 19:37:19 +08:00
imhao183 e63298f50b 实现群组/用户等信息变更通知 2020-10-19 09:09:53 +08:00
heavyrain2012 bc8baf3bcc 更新配置文件注释 2020-10-15 17:52:31 +08:00
dependabot[bot] 30a62cfc58 Bump junit from 4.8.2 to 4.13.1 in /broker
Bumps [junit](https://github.com/junit-team/junit4) from 4.8.2 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.8.2...r4.13.1)

Signed-off-by: dependabot[bot] <[email protected]>
2020-10-13 12:24:06 +00:00
imhao183 35b8133046 version 0.45 -> 0.46 2020-10-11 21:50:37 +08:00
imhao183 4a8500b99b 支持群主或管理员修改成员昵称 2020-10-11 21:23:45 +08:00
imhao183 c26e98b960 update proto 2020-10-11 21:19:13 +08:00
heavyrain2012 70fcc66672 添加默认文件传输助手用户 2020-10-06 12:14:22 +08:00
heavyrain2012 2538a6ca68 频道和机器人如果没有密钥,不允许使用api 2020-10-06 12:14:07 +08:00
heavyrain2012 6388f1b89c pc在线时,是否推送手机端信息定义修正 2020-10-05 22:49:02 +08:00
imhao183 ef1f25dab1 mute notification when pc online settings 2020-10-05 17:24:18 +08:00
imhao183 0a5c8a67bb 解决server api删除好友关系时不通知的问题 2020-09-28 09:45:38 +08:00
imhao183 ae3f0027ca 添加敏感词管理api测试代码 2020-09-20 08:40:22 +08:00
imhao183 76dedb3da7 添加server api发送好友请求功能 2020-09-15 09:05:42 +08:00
imhao183 580e9f80fb 重命名server api好友状态model 2020-09-15 09:05:34 +08:00
imhao183 63304c5c5f API获取用户好友列表按照时间排序 2020-09-14 22:47:45 +08:00
heavyrain2012 c377360049 version 0.44->0.45 2020-09-12 19:41:23 +08:00
imhao183 2e74a77e5b 优化用户关系的测试例 2020-09-10 18:47:14 +08:00
imhao183 90286e9484 解决server api无法删除好友问题 2020-09-10 18:46:43 +08:00
imhao183 7f479dd9e5 当A、B都向对方发出好友请求后,A接受好友邀请,A发送给B的好友邀请也要变成接受状态。
(cherry picked from commit a8d076a9ac7faa1a556caeaad239bb393824bd8b)
2020-09-03 15:37:22 +08:00
heavyrain2012 bae0805e64 创建用户时检查用户的有效性 2020-09-01 21:58:10 +08:00
imhao183 e5d63a8d5f 修正server api签名错误问题 2020-09-01 07:49:16 +08:00
imhao183 06fe70bd6f 兼容golang http请求 2020-08-29 09:42:29 +08:00
imhao183 5a14b2f2f0 兼容golang的http请求 2020-08-29 09:39:47 +08:00
123 changed files with 5491 additions and 864 deletions
+1 -1
View File
@@ -72,7 +72,7 @@
## 升级说明
1. 从0.42 版本增加了群成员数限制,默认为2000。如果您从之前的版本升级到这个版本或以后,需要注意到群成员数的限制。升级之后超出限制的群不受影响,但不能继续加人,如果您想修改默认值,可以在升级版本之后,修改t_setting表,把默认的大小改为您期望的人数。另外修改t_group表,把已经存在的群组max_member_count改成您期望的,然后重启。
2. 0.46和0.47版本升级到0.48及以后版本时,可能会提示flyway migrate 38错误,请执行 [修复脚本](https://github.com/wildfirechat/server/blob/wildfirechat/flyway_repaire_migrate_38.sql) 进行修复。0.46和0.47版本之外的版本不会出现此问题。
## 特别感谢
1. [moquette](https://github.com/moquette-io/moquette) 本项目是基于此项目二次开发而来,处理MQTT相关业务。
+67 -27
View File
@@ -20,9 +20,6 @@ port 1883
##客户端短链接端口
http_port 80
##WEB客户端长链接端口
websocket_port 8083
#管理端口
http.admin.port 18080
@@ -38,6 +35,11 @@ local_port 80
##是否使用内置DB。0使用mysql;1使用h2db;2使用mysql+mongodb。社区版只支持0和1,专业版支持2
embed.db 1
## 是否自动清理历史消息记录,当为true时,IM服务会定时扫描t_messages_x和t_user_messages_x表,清除掉3年前的历史消息。
## 如果不开启自动清理,需要手动清理t_messages_x和t_user_messages_x表内的历史数据,保存数据不能超过3年。
## 使用mongodb时次开关无效(因为mongodb设置了消息过期时间,会自动清理)。
db.auto_clean_history_messages true
##服务器管理接口密钥
http.admin.secret_key 123456
@@ -46,9 +48,6 @@ http.admin.secret_key 123456
##这个地方上线前要改为false
http.admin.no_check_time true
##客户端协议栈密钥,需要与客户端协议栈文件libemqq.cc文件中的aes_key值保持一致,16进制byte用逗号分割。这个密钥对安全性帮助不大,客户不要修改
client.proto.secret_key 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F
##用来生产im token的私钥,只在服务器使用,客户端不用。正式使用时为了安全一定要修改这个值,切记切记
token.key testim
@@ -78,6 +77,10 @@ message.disable_remote_search false
##允许客户端撤回消息时限,单位是秒。群组管理员或群主撤回群成员消息、server api不受此限制,可以撤回任意时限内的消息
message.recall_time_limit 120
## 禁止客户端发送消息类型,消息类型以逗号分开,下面3个值为示例,可以删除。
## 一般用于重要类型消息,比如交易、充值等,禁止客户端发送,仅限于服务器发送,提高安全性。
message.forbidden_client_send_types 3999,4000,4001
##禁止搜索用户
friend.disable_search false
@@ -108,6 +111,18 @@ chatroom.participant_idle_time 900000
## 用户向聊天室发送消息,自动加入聊天室
chatroom.rejoin_when_active true
## 是否允许客户端发送操作群的自定义群通知消息
group.allow_client_custom_operation_notification true
## 当群成员退出或者被移除时,是否同时给管理员和相关人员发送显式通知消息。
## 0 不发送,1 退群时发送,2 踢人时发送,3 退群和踢人时都发送。
group.visible_quit_or_kickoff_notification 0
## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开;
## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。
## 注意,修改本配置不会对已经同步的信息产生影响。
#user.hide_properties 3,4,5
#*********************************************************************
# hazelcase configuration
#*********************************************************************
@@ -166,40 +181,65 @@ server.multi_platform_notification false
#*********************************************************************
# Push server configuration
#*********************************************************************
##推送服务项目地址:https://github.com/wildfirechat/push_server。
##安卓推送服务器地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
push.android.server.address http://localhost:8085/android/push
##苹果推送服务器地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
push.ios.server.address http://localhost:8085/ios/push
#*********************************************************************
# User online status event callback
# 监控配置
#*********************************************************************
##用户在线状态事件回调地址
#user.online_status_callback http://localhost:8888/user/online_event
#monitor.exception_event_address http://localhost:8888/im_exception_event/
#*********************************************************************
# MongoDB configuration
# 各种事件回调
#*********************************************************************
#专业版支持,社区版请忽略
#mongodb.client_uri mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
#mongodb.client_uri mongodb://host1:27017,host2:27017,host3:27017/wfchat?replicaSet=myReplicaSet
mongodb.client_uri mongodb://wfc:123456@localhost:27017/wfchat
mongodb.database wfchat
#仅在第一次启动时会设置消息数据的过期时间,如果之后再修改将不生效。
#如果需要修改过期时间,请修改t_messages_x和t_user_message_x的索引过期时间,修改方法请行百度
mongodb.data_expire_days 1096
##用户在线状态事件回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#user.online_status_callback http://localhost:8888/im_event/user/online
##用户信息变动事件回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#relation.relation_update_callback http://localhost:8888/im_event/user/relation
##用户信息变动事件回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#user.user_info_update_callback http://localhost:8888/im_event/user/info
##消息转发地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#message.forward.url http://localhost:8888/im_event/message
##设备信息转发地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#things_message.forward.url http://localhost:8888/im_event/things/message
##群组信息变动事件回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#group.group_info_update_callback http://localhost:8888/im_event/group/info
##群组信息变动事件回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#group.group_member_update_callback http://localhost:8888/im_event/group/member
##频道信息变动回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#channel.channel_info_update_callback http://localhost:8888/im_event/channel/info
##聊天室信息变动回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#chatroom.chatroom_info_update_callback http://localhost:8888/im_event/chatroom/info
##聊天室成员变动回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#chatroom.chatroom_member_update_callback http://localhost:8888/im_event/chatroom/member
#*********************************************************************
# Sensitive configuration
#*********************************************************************
##文本敏感词过滤处理方法,0 发送失败;1 发送成功但消息被服务器直接丢弃;2 命中的敏感词被替换成***;3 记录并继续发送
sensitive.filter.type 0
#*********************************************************************
# Message forward configuration
#*********************************************************************
##消息转发地址
#message.forward.url http://localhost:8087/message/forward
##设备信息转发地址
#things_message.forward.url http://localhost:8087/device/forward
+1
View File
@@ -0,0 +1 @@
alter table `t_group` modify column `_searchable` int(11) NOT NULL DEFAULT 0;
+15
View File
@@ -0,0 +1,15 @@
DROP TABLE IF EXISTS `t_file`;
CREATE TABLE `t_file` (
`_mid` bigint(20) NOT NULL PRIMARY KEY,
`_from` varchar(64) NOT NULL,
`_type` tinyint NOT NULL DEFAULT 0,
`_target` varchar(64) NOT NULL,
`_line` int(11) NOT NULL DEFAULT 0,
`_name` varchar(128) DEFAULT '',
`_url` varchar(1024) NOT NULL DEFAULT '',
`_size` int(11) NOT NULL DEFAULT 0,
`_download_count` int(11) DEFAULT 0,
`_dt` bigint(20) NOT NULL,
INDEX `file_conv_index` (`_type`, `_line`, `_target`, `_mid`),
INDEX `file_user_index` (`_from`, `_mid`)
);
+3
View File
@@ -0,0 +1,3 @@
insert into t_user (`_uid`,`_name`,`_display_name`,`_portrait`,`_type`,`_dt`) values ('wfc_file_transfer','wfc_file_transfer','文件传输助手','https://static.wildfirechat.cn/wfc_file_transfer.png',1,1);
insert into t_robot (`_uid`,`_owner`,`_secret`,`_callback`,`_state`,`_dt`) values ('wfc_file_transfer', 'wfc_file_transfer', '', '', 0, 1);
+1
View File
@@ -0,0 +1 @@
alter table `t_channel` modify column `_status` int(11) NOT NULL DEFAULT 0;
+1
View File
@@ -0,0 +1 @@
alter table `t_user_messages` ADD INDEX `user_messages_mid_index` ( `_mid`);
@@ -0,0 +1 @@
alter table `t_group` modify column `_searchable` int(11) NOT NULL DEFAULT 0;
+18
View File
@@ -0,0 +1,18 @@
DROP TABLE IF EXISTS `t_file`;
CREATE TABLE `t_file` (
`_mid` bigint(20) NOT NULL PRIMARY KEY,
`_from` varchar(64) NOT NULL,
`_type` tinyint NOT NULL DEFAULT 0,
`_target` varchar(64) NOT NULL,
`_line` int(11) NOT NULL DEFAULT 0,
`_name` varchar(128) DEFAULT '',
`_url` varchar(1024) NOT NULL DEFAULT '',
`_size` int(11) NOT NULL DEFAULT 0,
`_download_count` int(11) DEFAULT 0,
`_dt` bigint(20) NOT NULL,
INDEX `file_conv_index` (`_type`, `_line`, `_target`, `_mid`),
INDEX `file_user_index` (`_from`, `_mid`)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
+3
View File
@@ -0,0 +1,3 @@
insert into t_user (`_uid`,`_name`,`_display_name`,`_portrait`,`_type`,`_dt`) values ('wfc_file_transfer','wfc_file_transfer','文件传输助手','https://static.wildfirechat.cn/wfc_file_transfer.png',1,1);
insert into t_robot (`_uid`,`_owner`,`_secret`,`_callback`,`_state`,`_dt`) values ('wfc_file_transfer', 'wfc_file_transfer', '', '', 0, 1);
@@ -0,0 +1 @@
alter table `t_channel` modify column `_status` int(11) NOT NULL DEFAULT 0;
+129
View File
@@ -0,0 +1,129 @@
alter table `t_user_messages` add INDEX `user_messages_mid_index` ( `_mid` );
alter table `t_user_messages_0` add INDEX `user_messages0_mid_index` ( `_mid` );
alter table `t_user_messages_1` add INDEX `user_messages1_mid_index` ( `_mid` );
alter table `t_user_messages_2` add INDEX `user_messages2_mid_index` ( `_mid` );
alter table `t_user_messages_3` add INDEX `user_messages3_mid_index` ( `_mid` );
alter table `t_user_messages_4` add INDEX `user_messages4_mid_index` ( `_mid` );
alter table `t_user_messages_5` add INDEX `user_messages5_mid_index` ( `_mid` );
alter table `t_user_messages_6` add INDEX `user_messages6_mid_index` ( `_mid` );
alter table `t_user_messages_7` add INDEX `user_messages7_mid_index` ( `_mid` );
alter table `t_user_messages_8` add INDEX `user_messages8_mid_index` ( `_mid` );
alter table `t_user_messages_9` add INDEX `user_messages9_mid_index` ( `_mid` );
alter table `t_user_messages_10` add INDEX `user_messages10_mid_index` ( `_mid` );
alter table `t_user_messages_11` add INDEX `user_messages11_mid_index` ( `_mid` );
alter table `t_user_messages_12` add INDEX `user_messages12_mid_index` ( `_mid` );
alter table `t_user_messages_13` add INDEX `user_messages13_mid_index` ( `_mid` );
alter table `t_user_messages_14` add INDEX `user_messages14_mid_index` ( `_mid` );
alter table `t_user_messages_15` add INDEX `user_messages15_mid_index` ( `_mid` );
alter table `t_user_messages_16` add INDEX `user_messages16_mid_index` ( `_mid` );
alter table `t_user_messages_17` add INDEX `user_messages17_mid_index` ( `_mid` );
alter table `t_user_messages_18` add INDEX `user_messages18_mid_index` ( `_mid` );
alter table `t_user_messages_19` add INDEX `user_messages19_mid_index` ( `_mid` );
alter table `t_user_messages_20` add INDEX `user_messages20_mid_index` ( `_mid` );
alter table `t_user_messages_21` add INDEX `user_messages21_mid_index` ( `_mid` );
alter table `t_user_messages_22` add INDEX `user_messages22_mid_index` ( `_mid` );
alter table `t_user_messages_23` add INDEX `user_messages23_mid_index` ( `_mid` );
alter table `t_user_messages_24` add INDEX `user_messages24_mid_index` ( `_mid` );
alter table `t_user_messages_25` add INDEX `user_messages25_mid_index` ( `_mid` );
alter table `t_user_messages_26` add INDEX `user_messages26_mid_index` ( `_mid` );
alter table `t_user_messages_27` add INDEX `user_messages27_mid_index` ( `_mid` );
alter table `t_user_messages_28` add INDEX `user_messages28_mid_index` ( `_mid` );
alter table `t_user_messages_29` add INDEX `user_messages29_mid_index` ( `_mid` );
alter table `t_user_messages_30` add INDEX `user_messages30_mid_index` ( `_mid` );
alter table `t_user_messages_31` add INDEX `user_messages31_mid_index` ( `_mid` );
alter table `t_user_messages_32` add INDEX `user_messages32_mid_index` ( `_mid` );
alter table `t_user_messages_33` add INDEX `user_messages33_mid_index` ( `_mid` );
alter table `t_user_messages_34` add INDEX `user_messages34_mid_index` ( `_mid` );
alter table `t_user_messages_35` add INDEX `user_messages35_mid_index` ( `_mid` );
alter table `t_user_messages_36` add INDEX `user_messages36_mid_index` ( `_mid` );
alter table `t_user_messages_37` add INDEX `user_messages37_mid_index` ( `_mid` );
alter table `t_user_messages_38` add INDEX `user_messages38_mid_index` ( `_mid` );
alter table `t_user_messages_39` add INDEX `user_messages39_mid_index` ( `_mid` );
alter table `t_user_messages_40` add INDEX `user_messages40_mid_index` ( `_mid` );
alter table `t_user_messages_41` add INDEX `user_messages41_mid_index` ( `_mid` );
alter table `t_user_messages_42` add INDEX `user_messages42_mid_index` ( `_mid` );
alter table `t_user_messages_43` add INDEX `user_messages43_mid_index` ( `_mid` );
alter table `t_user_messages_44` add INDEX `user_messages44_mid_index` ( `_mid` );
alter table `t_user_messages_45` add INDEX `user_messages45_mid_index` ( `_mid` );
alter table `t_user_messages_46` add INDEX `user_messages46_mid_index` ( `_mid` );
alter table `t_user_messages_47` add INDEX `user_messages47_mid_index` ( `_mid` );
alter table `t_user_messages_48` add INDEX `user_messages48_mid_index` ( `_mid` );
alter table `t_user_messages_49` add INDEX `user_messages49_mid_index` ( `_mid` );
alter table `t_user_messages_50` add INDEX `user_messages50_mid_index` ( `_mid` );
alter table `t_user_messages_51` add INDEX `user_messages51_mid_index` ( `_mid` );
alter table `t_user_messages_52` add INDEX `user_messages52_mid_index` ( `_mid` );
alter table `t_user_messages_53` add INDEX `user_messages53_mid_index` ( `_mid` );
alter table `t_user_messages_54` add INDEX `user_messages54_mid_index` ( `_mid` );
alter table `t_user_messages_55` add INDEX `user_messages55_mid_index` ( `_mid` );
alter table `t_user_messages_56` add INDEX `user_messages56_mid_index` ( `_mid` );
alter table `t_user_messages_57` add INDEX `user_messages57_mid_index` ( `_mid` );
alter table `t_user_messages_58` add INDEX `user_messages58_mid_index` ( `_mid` );
alter table `t_user_messages_59` add INDEX `user_messages59_mid_index` ( `_mid` );
alter table `t_user_messages_60` add INDEX `user_messages60_mid_index` ( `_mid` );
alter table `t_user_messages_61` add INDEX `user_messages61_mid_index` ( `_mid` );
alter table `t_user_messages_62` add INDEX `user_messages62_mid_index` ( `_mid` );
alter table `t_user_messages_63` add INDEX `user_messages63_mid_index` ( `_mid` );
alter table `t_user_messages_64` add INDEX `user_messages64_mid_index` ( `_mid` );
alter table `t_user_messages_65` add INDEX `user_messages65_mid_index` ( `_mid` );
alter table `t_user_messages_66` add INDEX `user_messages66_mid_index` ( `_mid` );
alter table `t_user_messages_67` add INDEX `user_messages67_mid_index` ( `_mid` );
alter table `t_user_messages_68` add INDEX `user_messages68_mid_index` ( `_mid` );
alter table `t_user_messages_69` add INDEX `user_messages69_mid_index` ( `_mid` );
alter table `t_user_messages_70` add INDEX `user_messages70_mid_index` ( `_mid` );
alter table `t_user_messages_71` add INDEX `user_messages71_mid_index` ( `_mid` );
alter table `t_user_messages_72` add INDEX `user_messages72_mid_index` ( `_mid` );
alter table `t_user_messages_73` add INDEX `user_messages73_mid_index` ( `_mid` );
alter table `t_user_messages_74` add INDEX `user_messages74_mid_index` ( `_mid` );
alter table `t_user_messages_75` add INDEX `user_messages75_mid_index` ( `_mid` );
alter table `t_user_messages_76` add INDEX `user_messages76_mid_index` ( `_mid` );
alter table `t_user_messages_77` add INDEX `user_messages77_mid_index` ( `_mid` );
alter table `t_user_messages_78` add INDEX `user_messages78_mid_index` ( `_mid` );
alter table `t_user_messages_79` add INDEX `user_messages79_mid_index` ( `_mid` );
alter table `t_user_messages_80` add INDEX `user_messages80_mid_index` ( `_mid` );
alter table `t_user_messages_81` add INDEX `user_messages81_mid_index` ( `_mid` );
alter table `t_user_messages_82` add INDEX `user_messages82_mid_index` ( `_mid` );
alter table `t_user_messages_83` add INDEX `user_messages83_mid_index` ( `_mid` );
alter table `t_user_messages_84` add INDEX `user_messages84_mid_index` ( `_mid` );
alter table `t_user_messages_85` add INDEX `user_messages85_mid_index` ( `_mid` );
alter table `t_user_messages_86` add INDEX `user_messages86_mid_index` ( `_mid` );
alter table `t_user_messages_87` add INDEX `user_messages87_mid_index` ( `_mid` );
alter table `t_user_messages_88` add INDEX `user_messages88_mid_index` ( `_mid` );
alter table `t_user_messages_89` add INDEX `user_messages89_mid_index` ( `_mid` );
alter table `t_user_messages_90` add INDEX `user_messages90_mid_index` ( `_mid` );
alter table `t_user_messages_91` add INDEX `user_messages91_mid_index` ( `_mid` );
alter table `t_user_messages_92` add INDEX `user_messages92_mid_index` ( `_mid` );
alter table `t_user_messages_93` add INDEX `user_messages93_mid_index` ( `_mid` );
alter table `t_user_messages_94` add INDEX `user_messages94_mid_index` ( `_mid` );
alter table `t_user_messages_95` add INDEX `user_messages95_mid_index` ( `_mid` );
alter table `t_user_messages_96` add INDEX `user_messages96_mid_index` ( `_mid` );
alter table `t_user_messages_97` add INDEX `user_messages97_mid_index` ( `_mid` );
alter table `t_user_messages_98` add INDEX `user_messages98_mid_index` ( `_mid` );
alter table `t_user_messages_99` add INDEX `user_messages99_mid_index` ( `_mid` );
alter table `t_user_messages_100` add INDEX `user_messages100_mid_index` ( `_mid` );
alter table `t_user_messages_101` add INDEX `user_messages101_mid_index` ( `_mid` );
alter table `t_user_messages_102` add INDEX `user_messages102_mid_index` ( `_mid` );
alter table `t_user_messages_103` add INDEX `user_messages103_mid_index` ( `_mid` );
alter table `t_user_messages_104` add INDEX `user_messages104_mid_index` ( `_mid` );
alter table `t_user_messages_105` add INDEX `user_messages105_mid_index` ( `_mid` );
alter table `t_user_messages_106` add INDEX `user_messages106_mid_index` ( `_mid` );
alter table `t_user_messages_107` add INDEX `user_messages107_mid_index` ( `_mid` );
alter table `t_user_messages_108` add INDEX `user_messages108_mid_index` ( `_mid` );
alter table `t_user_messages_109` add INDEX `user_messages109_mid_index` ( `_mid` );
alter table `t_user_messages_110` add INDEX `user_messages110_mid_index` ( `_mid` );
alter table `t_user_messages_111` add INDEX `user_messages111_mid_index` ( `_mid` );
alter table `t_user_messages_112` add INDEX `user_messages112_mid_index` ( `_mid` );
alter table `t_user_messages_113` add INDEX `user_messages113_mid_index` ( `_mid` );
alter table `t_user_messages_114` add INDEX `user_messages114_mid_index` ( `_mid` );
alter table `t_user_messages_115` add INDEX `user_messages115_mid_index` ( `_mid` );
alter table `t_user_messages_116` add INDEX `user_messages116_mid_index` ( `_mid` );
alter table `t_user_messages_117` add INDEX `user_messages117_mid_index` ( `_mid` );
alter table `t_user_messages_118` add INDEX `user_messages118_mid_index` ( `_mid` );
alter table `t_user_messages_119` add INDEX `user_messages119_mid_index` ( `_mid` );
alter table `t_user_messages_120` add INDEX `user_messages120_mid_index` ( `_mid` );
alter table `t_user_messages_121` add INDEX `user_messages121_mid_index` ( `_mid` );
alter table `t_user_messages_122` add INDEX `user_messages122_mid_index` ( `_mid` );
alter table `t_user_messages_123` add INDEX `user_messages123_mid_index` ( `_mid` );
alter table `t_user_messages_124` add INDEX `user_messages124_mid_index` ( `_mid` );
alter table `t_user_messages_125` add INDEX `user_messages125_mid_index` ( `_mid` );
alter table `t_user_messages_126` add INDEX `user_messages126_mid_index` ( `_mid` );
alter table `t_user_messages_127` add INDEX `user_messages127_mid_index` ( `_mid` );
+2 -9
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.44</version>
<version>0.53</version>
</parent>
<artifactId>moquette-broker</artifactId>
@@ -132,7 +132,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
@@ -198,13 +198,6 @@
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
@@ -15,6 +15,7 @@ public class PushMessage {
public int convType;
public String target;
public String targetName;
public String userId;
public int line;
public int cntType;
public long serverTime;
@@ -42,7 +43,16 @@ public class PushMessage {
this.cntType = messageContentType;
this.serverTime = serverTime;
this.unReceivedMsg = unReceivedMsg;
this.pushMessageType = (cntType == 400 ? PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE : (cntType == 402 ? PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE : PushServer.PushMessageType.PUSH_MESSAGE_TYPE_NORMAL));
if (cntType == 400) {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE;
} else if(cntType == 402) {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE;
} else if(cntType == 401) {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_ANSWER;
} else {
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_NORMAL;
}
this.mentionedType = mentionedType;
this.isHiddenDetail = isHiddenDetail;
this.language = language;
@@ -8,12 +8,11 @@
package cn.wildfirechat.push;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import io.moquette.persistence.MemorySessionStore;
import io.moquette.server.config.IConfig;
import io.moquette.spi.ClientSession;
import io.moquette.spi.ISessionsStore;
import io.netty.util.internal.StringUtil;
import org.slf4j.Logger;
@@ -35,6 +34,7 @@ public class PushServer {
int PUSH_MESSAGE_TYPE_VOIP_INVITE = 1;
int PUSH_MESSAGE_TYPE_VOIP_BYE = 2;
int PUSH_MESSAGE_TYPE_FRIEND_REQUEST = 3;
int PUSH_MESSAGE_TYPE_VOIP_ANSWER = 4;
}
private static PushServer INSTANCE = new PushServer();
@@ -64,7 +64,7 @@ public class PushServer {
pushMessageInternel(pushMessage, deviceId, pushContent);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.PUSH_SERVER_Exception);
}
});
}
@@ -90,6 +90,7 @@ public class PushServer {
pushMessage.pushContent = pushContent;
pushMessage.deviceToken = session.getDeviceToken();
pushMessage.unReceivedMsg = badge;
pushMessage.userId = session.getUsername();
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_Android) {
String url = androidPushServerUrl;
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS) {
@@ -80,9 +80,12 @@ public class LoFileServer {
channel = b.bind(port).sync().channel();
Logger.info("***** Welcome To LoServer on port [{}], startting spend {}ms *****", port, DateUtil.spendMs(start));
} finally {
}
} catch (Exception e) {
e.printStackTrace();
Logger.error("端口 {} 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep {}", port, port);
System.out.println("端口 " + port + " 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep " + port);
System.exit(-1);
}
}
public void shutdown() {
if (this.channel != null) {
@@ -62,6 +62,7 @@ public class LoServer {
registerAllAction();
int bindingPort = port;
try {
final ServerBootstrap b = new ServerBootstrap();
final ServerBootstrap adminB = new ServerBootstrap();
@@ -87,6 +88,7 @@ public class LoServer {
channel = b.bind(port).sync().channel();
bindingPort = adminPort;
adminB.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 10240) // 服务端可连接队列大小
@@ -108,10 +110,14 @@ public class LoServer {
adminChannel = adminB.bind(adminPort).sync().channel();
Logger.info("***** Welcome To LoServer on port [{},{}], startting spend {}ms *****", port, adminPort, DateUtil.spendMs(start));
} finally {
}
} catch (Exception e) {
e.printStackTrace();
Logger.error("端口 {} 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep {}", bindingPort, bindingPort);
System.out.println("端口 " + bindingPort + " 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep " + bindingPort);
System.exit(-1);
}
}
public void shutdown() {
if (this.channel!= null) {
this.channel.close();
@@ -110,7 +110,7 @@ public class FileAction extends Action {
// 路径安全检查
String path = httpPath.substring(0, httpPath.lastIndexOf("/"));
if (path.contains("/.") || path.contains("./") || path.charAt(0) == '.' || path.charAt(path.length() - 1) == '.' || ReUtil.isMatch(INSECURE_URI, path)) {
if (path.contains("/.") || path.contains("./") || ReUtil.isMatch(INSECURE_URI, path)) {
return null;
}
@@ -0,0 +1,87 @@
/*
* 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.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputAddFriendRequest;
import cn.wildfirechat.pojos.InputUpdateAlias;
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 io.moquette.persistence.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Friend_Send_Request)
@HttpMethod("POST")
public class AddFriendRequestAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputAddFriendRequest input = getRequestBody(request.getNettyRequest(), InputAddFriendRequest.class);
if (StringUtil.isNullOrEmpty(input.getUserId()) || StringUtil.isNullOrEmpty(input.getFriendUid())) {
sendResponse(response, ErrorCode.INVALID_PARAMETER, null);
return true;
}
WFCMessage.AddFriendRequest addFriendRequest = WFCMessage.AddFriendRequest.newBuilder().setReason(input.getReason()).setTargetUid(input.getFriendUid()).build();
RPCCenter.getInstance().sendRequest(input.getUserId(), null, IMTopic.AddFriendRequestTopic, addFriendRequest.toByteArray(), input.getUserId(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, input.isForce());
return false;
}
return true;
}
}
@@ -44,9 +44,20 @@ abstract public class AdminAction extends Action {
if (!mLimitCounter.isGranted("admin")) {
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
}
String nonce = request.getHeader("nonce");
if (StringUtil.isNullOrEmpty(nonce)) {
nonce = request.getHeader("Nonce");
}
String timestamp = request.getHeader("timestamp");
if (StringUtil.isNullOrEmpty(timestamp)) {
timestamp = request.getHeader("Timestamp");
}
String sign = request.getHeader("sign");
if (StringUtil.isNullOrEmpty(sign)) {
sign = request.getHeader("Sign");
}
if (StringUtil.isNullOrEmpty(nonce) || StringUtil.isNullOrEmpty(timestamp) || StringUtil.isNullOrEmpty(sign)) {
return ErrorCode.INVALID_PARAMETER;
}
@@ -9,6 +9,7 @@
package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
@@ -63,7 +64,7 @@ public class CreateRobotAction extends AdminAction {
messagesStore.addUserInfo(newUser, inputCreateRobot.getPassword());
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
response.setContent(new Gson().toJson(result));
@@ -9,6 +9,7 @@
package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
@@ -25,7 +26,6 @@ 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;
@@ -88,7 +88,7 @@ public class CreateUserAction extends AdminAction {
messagesStore.addUserInfo(newUserBuilder.build(), inputCreateUser.getPassword());
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
response.setContent(new Gson().toJson(result));
@@ -16,7 +16,7 @@ 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 cn.wildfirechat.pojos.InputFriendRequest;
import cn.wildfirechat.pojos.InputUpdateFriendStatusRequest;
import io.moquette.persistence.RPCCenter;
import io.moquette.persistence.TargetEntry;
import io.netty.buffer.ByteBuf;
@@ -41,7 +41,7 @@ public class FriendRelationAction extends AdminAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputFriendRequest friendAdd = getRequestBody(request.getNettyRequest(), InputFriendRequest.class);
InputUpdateFriendStatusRequest friendAdd = getRequestBody(request.getNettyRequest(), InputUpdateFriendStatusRequest.class);
if (friendAdd != null
&& !StringUtil.isNullOrEmpty(friendAdd.getUserId())
&& !StringUtil.isNullOrEmpty(friendAdd.getFriendUid())
@@ -23,6 +23,7 @@ import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@Route(APIPath.Friend_Get_List)
@@ -40,6 +41,7 @@ public class FriendRelationGetAction extends AdminAction {
InputUserId inputGetFriendList = getRequestBody(request.getNettyRequest(), InputUserId.class);
List<FriendData> dataList = messagesStore.getFriendList(inputGetFriendList.getUserId(), null, 0);
List<String> list = new ArrayList<>();
dataList.sort(Comparator.comparingLong(FriendData::getTimestamp));
for (FriendData data : dataList) {
if (data.getState() == 0) {
list.add(data.getFriendUid());
@@ -0,0 +1,52 @@
/*
* 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.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputOutputUserBlockStatus;
import cn.wildfirechat.pojos.StringPairPojo;
import com.google.gson.Gson;
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 io.moquette.persistence.RPCCenter;
import io.moquette.persistence.TargetEntry;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
@Route(APIPath.User_Kickoff_Client)
@HttpMethod("POST")
public class KickoffUserClientAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
StringPairPojo pojo = getRequestBody(request.getNettyRequest(), StringPairPojo.class);
if (pojo != null && !StringUtil.isNullOrEmpty(pojo.getFirst())) {
sessionsStore.kickoffUserClient(pojo.getFirst(), pojo.getSecond());
sendResponse(response, ErrorCode.ERROR_CODE_SUCCESS, null);
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,85 @@
/*
* 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.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputKickoffGroupMember;
import cn.wildfirechat.pojos.InputSetGroupMemberAlias;
import com.google.gson.Gson;
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 io.moquette.persistence.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Group_Set_Member_Alias)
@HttpMethod("POST")
public class ModifyGroupMemberAliasAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputSetGroupMemberAlias inputSetGroupMemberAlias = getRequestBody(request.getNettyRequest(), InputSetGroupMemberAlias.class);
if (inputSetGroupMemberAlias.isValide()) {
RPCCenter.getInstance().sendRequest(inputSetGroupMemberAlias.getOperator(), null, IMTopic.ModifyGroupMemberAliasTopic, inputSetGroupMemberAlias.toProtoGroupRequest().toByteArray(), inputSetGroupMemberAlias.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, true);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,84 @@
/*
* 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.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.RecallMessageData;
import cn.wildfirechat.pojos.RecallMultiCastMessageData;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
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 io.moquette.persistence.RPCCenter;
import io.moquette.persistence.TargetEntry;
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 io.netty.util.internal.StringUtil;
import win.liyufan.im.IMTopic;
import java.util.concurrent.Executor;
@Route(APIPath.Msg_RecallMultiCast)
@HttpMethod("POST")
public class RecallMultiCastMessageAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
RecallMultiCastMessageData recallMessageData = getRequestBody(request.getNettyRequest(), RecallMultiCastMessageData.class);
if (recallMessageData != null && !StringUtil.isNullOrEmpty(recallMessageData.operator)) {
WFCMessage.RecallMultiCastMessageRequest recallRequest = WFCMessage.RecallMultiCastMessageRequest.newBuilder().setMessageId(recallMessageData.messageUid).addAllReceiver(recallMessageData.receivers).build();
RPCCenter.getInstance().sendRequest(recallMessageData.operator, null, IMTopic.RecallMultiCastMessageTopic, recallRequest.toByteArray(), recallMessageData.operator, TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
sendResponse(response, errorCode, null);
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, true);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,61 @@
/*
* 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.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.pojos.InputUserId;
import cn.wildfirechat.pojos.OutputStringList;
import cn.wildfirechat.pojos.RelationPojo;
import cn.wildfirechat.pojos.StringPairPojo;
import com.google.gson.Gson;
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.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@Route(APIPath.Relation_Get)
@HttpMethod("POST")
public class RelationGetAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
StringPairPojo input = getRequestBody(request.getNettyRequest(), StringPairPojo.class);
FriendData data = messagesStore.getFriendData(input.getFirst(), input.getSecond());
RelationPojo out = new RelationPojo();
out.userId = input.getFirst();
out.targetId = input.getSecond();
if(data != null ) {
out.isFriend = data.getState() == 0;
out.isBlacked = data.getBlacked() == 1;
out.alias = data.getAlias();
out.extra = data.getExtra();
}
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.ok(out);
response.setContent(new Gson().toJson(result));
}
return true;
}
}
@@ -8,11 +8,11 @@
package com.xiaoleilu.loServer.action.channel;
import cn.wildfirechat.common.IMExceptionEvent;
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;
@@ -34,9 +34,21 @@ abstract public class ChannelAction extends Action {
@Override
public ErrorCode preAction(Request request, Response response) {
String nonce = request.getHeader("nonce");
if (StringUtil.isNullOrEmpty(nonce)) {
nonce = request.getHeader("Nonce");
}
String timestamp = request.getHeader("timestamp");
if (StringUtil.isNullOrEmpty(timestamp)) {
timestamp = request.getHeader("Timestamp");
}
String sign = request.getHeader("sign");
if (StringUtil.isNullOrEmpty(sign)) {
sign = request.getHeader("Sign");
}
String cid = request.getHeader("cid");
if (StringUtil.isNullOrEmpty(cid)) {
cid = request.getHeader("Cid");
}
if (StringUtil.isNullOrEmpty(nonce) || StringUtil.isNullOrEmpty(timestamp) || StringUtil.isNullOrEmpty(sign) || StringUtil.isNullOrEmpty(cid)) {
return ErrorCode.INVALID_PARAMETER;
@@ -51,7 +63,7 @@ abstract public class ChannelAction extends Action {
ts = Long.parseLong(timestamp);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.CHANNEL_API_Exception);
return ErrorCode.INVALID_PARAMETER;
}
@@ -63,6 +75,10 @@ abstract public class ChannelAction extends Action {
if (channelInfo == null) {
return ErrorCode.INVALID_PARAMETER;
}
if (StringUtil.isNullOrEmpty(channelInfo.getSecret())) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
String str = nonce + "|" + channelInfo.getSecret() + "|" + timestamp;
String localSign = DigestUtils.sha1Hex(str);
@@ -0,0 +1,86 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputAddGroupMember;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.admin.AdminAction;
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.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Robot_Group_Member_Add)
@HttpMethod("POST")
public class AddGroupMemberAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputAddGroupMember inputAddGroupMember = getRequestBody(request.getNettyRequest(), InputAddGroupMember.class);
inputAddGroupMember.setOperator(robot.getUid());
if (inputAddGroupMember.isValide()) {
RPCCenter.getInstance().sendRequest(inputAddGroupMember.getOperator(), null, IMTopic.AddGroupMemberTopic, inputAddGroupMember.toProtoGroupRequest().toByteArray(), inputAddGroupMember.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, false);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,95 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputCreateGroup;
import cn.wildfirechat.pojos.OutputCreateGroupResult;
import cn.wildfirechat.pojos.PojoGroupInfo;
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.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.moquette.persistence.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Robot_Create_Group)
@HttpMethod("POST")
public class CreateGroupAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputCreateGroup inputCreateGroup = getRequestBody(request.getNettyRequest(), InputCreateGroup.class);
inputCreateGroup.setOperator(robot.getUid());
inputCreateGroup.getGroup().getGroup_info().setOwner(robot.getUid());
if (inputCreateGroup.isValide()) {
PojoGroupInfo group_info = inputCreateGroup.getGroup().getGroup_info();
WFCMessage.CreateGroupRequest createGroupRequest = inputCreateGroup.toProtoGroupRequest();
RPCCenter.getInstance().sendRequest(inputCreateGroup.getOperator(), null, IMTopic.CreateGroupTopic, createGroupRequest.toByteArray(), inputCreateGroup.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] 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 groupId = new String(data);
sendResponse(response, null, new OutputCreateGroupResult(groupId));
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, false);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,41 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.RobotCallbackPojo;
import com.google.gson.Gson;
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 io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
@Route(APIPath.Robot_Delete_Callback)
@HttpMethod("POST")
public class DeleteCallbackAction extends RobotAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
if(!StringUtil.isNullOrEmpty(robot.getCallback())) {
robot = robot.toBuilder().clearCallback().setState(0).build();
messagesStore.addRobot(robot);
}
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.ok();
response.setContent(new Gson().toJson(result));
}
return true;
}
}
@@ -0,0 +1,86 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputDismissGroup;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.admin.AdminAction;
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.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Robot_Group_Dismiss)
@HttpMethod("POST")
public class DismissGroupAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputDismissGroup inputDismissGroup = getRequestBody(request.getNettyRequest(), InputDismissGroup.class);
inputDismissGroup.setOperator(robot.getUid());
if (inputDismissGroup.isValide()) {
RPCCenter.getInstance().sendRequest(inputDismissGroup.getOperator(), null, IMTopic.DismissGroupTopic, inputDismissGroup.toProtoGroupRequest().toByteArray(), inputDismissGroup.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, false);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,42 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputGetUserInfo;
import cn.wildfirechat.pojos.InputOutputUserInfo;
import cn.wildfirechat.pojos.RobotCallbackPojo;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
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 io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
@Route(APIPath.Robot_Get_Callback)
@HttpMethod("POST")
public class GetCallbackAction extends RobotAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
RobotCallbackPojo out = new RobotCallbackPojo();
out.setUrl(robot.getCallback());
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.ok(out);
response.setContent(new Gson().toJson(result));
}
return true;
}
}
@@ -0,0 +1,70 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputGetGroup;
import cn.wildfirechat.pojos.PojoGroupInfo;
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.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.Robot_Group_Get_Info)
@HttpMethod("POST")
public class GetGroupInfoAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputGetGroup inputGetGroup = getRequestBody(request.getNettyRequest(), InputGetGroup.class);
if (inputGetGroup != null
&& (!StringUtil.isNullOrEmpty(inputGetGroup.getGroupId()))) {
WFCMessage.GroupInfo groupInfo = messagesStore.getGroupInfo(inputGetGroup.getGroupId());
response.setStatus(HttpResponseStatus.OK);
RestResult result;
if (groupInfo == null) {
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
} else {
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
pojoGroupInfo.setExtra(groupInfo.getExtra());
pojoGroupInfo.setName(groupInfo.getName());
pojoGroupInfo.setOwner(groupInfo.getOwner());
pojoGroupInfo.setPortrait(groupInfo.getPortrait());
pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
pojoGroupInfo.setType(groupInfo.getType());
result = RestResult.ok(pojoGroupInfo);
}
response.setContent(new Gson().toJson(result));
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,90 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputGetGroup;
import cn.wildfirechat.pojos.OutputGroupMemberList;
import cn.wildfirechat.pojos.PojoGroupMember;
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.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;
import java.util.ArrayList;
import java.util.List;
@Route(APIPath.Robot_Group_Member_List)
@HttpMethod("POST")
public class GetGroupMembersAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputGetGroup inputGetGroup = getRequestBody(request.getNettyRequest(), InputGetGroup.class);
String robotId = robot.getUid();
if (inputGetGroup != null
&& (!StringUtil.isNullOrEmpty(inputGetGroup.getGroupId()))) {
List<WFCMessage.GroupMember> members = new ArrayList<>();
ErrorCode errorCode = messagesStore.getGroupMembers(null, inputGetGroup.getGroupId(), 0, members);
response.setStatus(HttpResponseStatus.OK);
RestResult result;
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
result = RestResult.resultOf(errorCode);
} else {
OutputGroupMemberList out = new OutputGroupMemberList();
out.setMembers(new ArrayList<>());
boolean isInGroup = false;
for (WFCMessage.GroupMember member : members) {
if (member.getType() == ProtoConstants.GroupMemberType.GroupMemberType_Removed) {
continue;
}
if(member.getMemberId().equals(robotId)) {
isInGroup = true;
}
PojoGroupMember pm = new PojoGroupMember();
pm.setMember_id(member.getMemberId());
pm.setAlias(member.getAlias());
pm.setType(member.getType());
out.getMembers().add(pm);
}
if(!isInGroup) {
out.getMembers().clear();
}
result = RestResult.ok(out);
}
response.setContent(new Gson().toJson(result));
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,86 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputKickoffGroupMember;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.admin.AdminAction;
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.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Robot_Group_Member_Kickoff)
@HttpMethod("POST")
public class KickoffGroupMemberAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputKickoffGroupMember inputKickoffGroupMember = getRequestBody(request.getNettyRequest(), InputKickoffGroupMember.class);
inputKickoffGroupMember.setOperator(robot.getUid());
if (inputKickoffGroupMember.isValide()) {
RPCCenter.getInstance().sendRequest(inputKickoffGroupMember.getOperator(), null, IMTopic.KickoffGroupMemberTopic, inputKickoffGroupMember.toProtoGroupRequest().toByteArray(), inputKickoffGroupMember.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, false);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,86 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputModifyGroupInfo;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.admin.AdminAction;
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.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Robot_Group_Modify_Info)
@HttpMethod("POST")
public class ModifyGroupInfoAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputModifyGroupInfo inputAddGroupMember = getRequestBody(request.getNettyRequest(), InputModifyGroupInfo.class);
inputAddGroupMember.setOperator(robot.getUid());
if (inputAddGroupMember.isValide()) {
RPCCenter.getInstance().sendRequest(inputAddGroupMember.getOperator(), null, IMTopic.ModifyGroupInfoTopic, inputAddGroupMember.toProtoGroupRequest().toByteArray(), inputAddGroupMember.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, false);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,86 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputSetGroupMemberAlias;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.admin.AdminAction;
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.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Robot_Group_Set_Member_Alias)
@HttpMethod("POST")
public class ModifyGroupMemberAliasAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputSetGroupMemberAlias inputSetGroupMemberAlias = getRequestBody(request.getNettyRequest(), InputSetGroupMemberAlias.class);
inputSetGroupMemberAlias.setOperator(robot.getUid());
if (inputSetGroupMemberAlias.isValide()) {
RPCCenter.getInstance().sendRequest(inputSetGroupMemberAlias.getOperator(), null, IMTopic.ModifyGroupMemberAliasTopic, inputSetGroupMemberAlias.toProtoGroupRequest().toByteArray(), inputSetGroupMemberAlias.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, false);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,86 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputQuitGroup;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.admin.AdminAction;
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.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Robot_Group_Member_Quit)
@HttpMethod("POST")
public class QuitGroupMemberAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputQuitGroup inputQuitGroup = getRequestBody(request.getNettyRequest(), InputQuitGroup.class);
inputQuitGroup.setOperator(robot.getUid());
if (inputQuitGroup.isValide()) {
RPCCenter.getInstance().sendRequest(inputQuitGroup.getOperator(), null, IMTopic.QuitGroupTopic, inputQuitGroup.toProtoGroupRequest().toByteArray(), inputQuitGroup.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, false);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -8,13 +8,13 @@
package com.xiaoleilu.loServer.action.robot;
import cn.wildfirechat.common.IMExceptionEvent;
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.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;
@@ -38,9 +38,22 @@ abstract public class RobotAction extends Action {
@Override
public ErrorCode preAction(Request request, Response response) {
String nonce = request.getHeader("nonce");
if (StringUtil.isNullOrEmpty(nonce)) {
nonce = request.getHeader("Nonce");
}
String timestamp = request.getHeader("timestamp");
if (StringUtil.isNullOrEmpty(timestamp)) {
timestamp = request.getHeader("Timestamp");
}
String sign = request.getHeader("sign");
if (StringUtil.isNullOrEmpty(sign)) {
sign = request.getHeader("Sign");
}
String rid = request.getHeader("rid");
if (StringUtil.isNullOrEmpty(rid)) {
rid = request.getHeader("Rid");
}
if (StringUtil.isNullOrEmpty(nonce) || StringUtil.isNullOrEmpty(timestamp) || StringUtil.isNullOrEmpty(sign) || StringUtil.isNullOrEmpty(rid)) {
return ErrorCode.INVALID_PARAMETER;
}
@@ -54,7 +67,7 @@ abstract public class RobotAction extends Action {
ts = Long.parseLong(timestamp);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ROBOT_API_Exception);
return ErrorCode.INVALID_PARAMETER;
}
@@ -67,6 +80,10 @@ abstract public class RobotAction extends Action {
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
if (StringUtil.isNullOrEmpty(robot.getSecret())) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
String str = nonce + "|" + robot.getSecret() + "|" + timestamp;
String localSign = DigestUtils.sha1Hex(str);
return localSign.equals(sign) ? ErrorCode.ERROR_CODE_SUCCESS : ErrorCode.ERROR_CODE_AUTH_FAILURE;
@@ -95,7 +112,7 @@ abstract public class RobotAction extends Action {
return t;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ROBOT_API_Exception);
}
}
return null;
@@ -0,0 +1,51 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputGetGroup;
import cn.wildfirechat.pojos.RobotCallbackPojo;
import com.google.gson.Gson;
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 io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
@Route(APIPath.Robot_Set_Callback)
@HttpMethod("POST")
public class SetCallbackAction extends RobotAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
RobotCallbackPojo input = getRequestBody(request.getNettyRequest(), RobotCallbackPojo.class);
if(!StringUtil.isNullOrEmpty(input.getUrl())) {
if(!input.getUrl().equals(robot.getCallback()) && robot.getState() != 1) {
robot = robot.toBuilder().setCallback(input.getUrl()).setState(1).build();
messagesStore.addRobot(robot);
}
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.ok();
response.setContent(new Gson().toJson(result));
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,86 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputTransferGroup;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.admin.AdminAction;
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.RPCCenter;
import io.moquette.persistence.TargetEntry;
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.concurrent.Executor;
@Route(APIPath.Robot_Group_Transfer)
@HttpMethod("POST")
public class TransferGroupAction extends RobotAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputTransferGroup inputDismissGroup = getRequestBody(request.getNettyRequest(), InputTransferGroup.class);
inputDismissGroup.setOperator(robot.getUid());
if (inputDismissGroup.isValide()) {
RPCCenter.getInstance().sendRequest(inputDismissGroup.getOperator(), null, IMTopic.TransferGroupTopic, inputDismissGroup.toProtoGroupRequest().toByteArray(), inputDismissGroup.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
@Override
public void onSuccess(byte[] result) {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeBytes(result);
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, null, null);
} else {
sendResponse(response, errorCode, null);
}
}
@Override
public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null);
}
@Override
public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
}
@Override
public Executor getResponseExecutor() {
return command -> {
ctx.executor().execute(command);
};
}
}, false);
return false;
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
}
}
return true;
}
}
@@ -0,0 +1,94 @@
/*
* 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.robot;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.IntStringPairPojo;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
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 io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import static cn.wildfirechat.pojos.MyInfoType.*;
@Route(APIPath.Robot_Update_Profile)
@HttpMethod("POST")
public class UpdateProfileAction extends RobotAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
IntStringPairPojo input = getRequestBody(request.getNettyRequest(), IntStringPairPojo.class);
WFCMessage.User.Builder builder = messagesStore.getUserInfo(robot.getUid()).toBuilder();
boolean modified = false;
switch (input.getIntValue()) {
case Modify_DisplayName:
builder.setDisplayName(input.getStrValue());
modified = true;
break;
case Modify_Gender:
builder.setGender(Integer.parseInt(input.getStrValue()));
modified = true;
break;
case Modify_Portrait:
builder.setPortrait(input.getStrValue());
modified = true;
break;
//不允许修改电话号码,如果修改电话号码必须通过admin进行修改
// case Modify_Mobile:
// builder.setMobile(input.getStrValue());
// modified = true;
// break;
case Modify_Email:
builder.setEmail(input.getStrValue());
modified = true;
break;
case Modify_Address:
builder.setAddress(input.getStrValue());
modified = true;
break;
case Modify_Company:
builder.setCompany(input.getStrValue());
modified = true;
break;
case Modify_Social:
builder.setSocial(input.getStrValue());
modified = true;
break;
case Modify_Extra:
builder.setExtra(input.getStrValue());
modified = true;
break;
default:
break;
}
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.ok();
if(modified) {
try {
messagesStore.updateUserInfo(builder.build());
} catch (Exception e) {
e.printStackTrace();
result.setErrorCode(ErrorCode.ERROR_CODE_SERVER_ERROR);
}
}
response.setContent(new Gson().toJson(result));
}
return true;
}
}
@@ -1,11 +1,7 @@
package com.xiaoleilu.loServer.handler;
import java.io.IOException;
import com.hazelcast.core.HazelcastInstance;
import cn.wildfirechat.common.IMExceptionEvent;
import com.xiaoleilu.hutool.lang.Singleton;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.StaticLog;
import com.xiaoleilu.loServer.ServerSetting;
import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.UnknownErrorAction;
@@ -53,7 +49,7 @@ abstract public class ActionHandler extends SimpleChannelInboundHandler<FullHttp
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(Logger, e);
Utility.printExecption(Logger, e, IMExceptionEvent.EventType.SHORT_LINK_Exception);
Action errorAction = ServerSetting.getErrorAction(ServerSetting.MAPPING_ERROR);
request.putParam(UnknownErrorAction.ERROR_PARAM_NAME, e);
response.setContent(e.toString());
@@ -11,8 +11,6 @@ import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.activation.MimetypesFileTypeMap;
import static io.netty.handler.codec.http.HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_RANGE;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
@@ -22,7 +20,6 @@ import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
public class HttpResponseHelper {
private static final Logger logger = LoggerFactory.getLogger(HttpResponseHelper.class);
private static final MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
/**
* sendResponse
@@ -149,7 +146,7 @@ public static String getContentType(String fileName) {
if (fileExtName.equals("png")) { // MimetypesFileTypeMap目前缺少png类型
return "image/png";
} else {
return mimetypesFileTypeMap.getContentType(fileName);
return "application/octet-stream";
}
}
@@ -357,8 +357,8 @@ public class Response {
final DefaultHttpResponse defaultHttpResponse = new DefaultHttpResponse(httpVersion, status);
// headers
final HttpHeaders httpHeaders = defaultHttpResponse.headers().add(headers);
HttpHeaders httpHeaders = defaultHttpResponse.headers().add(headers);
httpHeaders.set(HttpHeaderNames.CONTENT_TYPE.toString(), contentType);
// Cookies
for (Cookie cookie : cookies) {
httpHeaders.add(HttpHeaderNames.SET_COOKIE.toString(), ServerCookieEncoder.LAX.encode(cookie));
@@ -35,7 +35,6 @@ public final class BrokerConstants {
public static final String DEFAULT_MOQUETTE_STORE_MAP_DB_FILENAME = "moquette_store.mapdb";
public static final String DEFAULT_PERSISTENT_PATH = System.getProperty("user.dir") + File.separator
+ DEFAULT_MOQUETTE_STORE_MAP_DB_FILENAME;
public static final String WEB_SOCKET_PORT_PROPERTY_NAME = "websocket_port";
public static final String WSS_PORT_PROPERTY_NAME = "secure_websocket_port";
public static final String SSL_PORT_PROPERTY_NAME = "ssl_port";
public static final String JKS_PATH_PROPERTY_NAME = "jks_path";
@@ -47,7 +46,6 @@ public final class BrokerConstants {
public static final String DB_AUTHENTICATOR_QUERY = "authenticator.db.query";
public static final String DB_AUTHENTICATOR_DIGEST = "authenticator.db.digest";
public static final int PORT = 1883;
public static final int WEBSOCKET_PORT = 8080;
public static final String DISABLED_PORT_BIND = "disabled";
public static final String HOST = "0.0.0.0";
public static final String NEED_CLIENT_AUTH = "need_client_auth";
@@ -92,8 +90,22 @@ public final class BrokerConstants {
public static final String PUSH_ANDROID_SERVER_ADDRESS = "push.android.server.address";
public static final String PUSH_IOS_SERVER_ADDRESS = "push.ios.server.address";
public static final String MONITOR_Exception_Event_Address = "monitor.exception_event_address";
public static final String USER_ONLINE_STATUS_CALLBACK = "user.online_status_callback";
public static final String GROUP_INFO_UPDATE_CALLBACK = "group.group_info_update_callback";
public static final String GROUP_MEMBER_UPDATE_CALLBACK = "group.group_member_update_callback";
public static final String RELATION_UPDATE_CALLBACK = "relation.relation_update_callback";
public static final String USER_INFO_UPDATE_CALLBACK = "user.user_info_update_callback";
public static final String CHANNEL_INFO_UPDATE_CALLBACK = "channel.channel_info_update_callback";
public static final String CHATROOM_INFO_UPDATE_CALLBACK = "chatroom.chatroom_info_update_callback";
public static final String CHATROOM_MEMBER_UPDATE_CALLBACK = "chatroom.chatroom_member_update_callback";
public static final String HZ_Cluster_Node_External_IP = "node_external_ip";
public static final String HZ_Cluster_Node_External_Long_Port = "node_external_long_port";
public static final String HZ_Cluster_Node_External_Short_Port = "node_external_short_port";
@@ -101,13 +113,11 @@ public final class BrokerConstants {
public static final String HTTP_SERVER_SECRET_KEY = "http.admin.secret_key";
public static final String HTTP_SERVER_API_NO_CHECK_TIME = "http.admin.no_check_time";
public static final String CLIENT_PROTO_SECRET_KEY = "client.proto.secret_key";
public static final String TOKEN_SECRET_KEY = "token.key";
public static final String TOKEN_EXPIRE_TIME = "token.expire_time";
public static final String EMBED_DB_PROPERTY_NAME = "embed.db";
public static final String HZ_Cluster_Master_Node = "master_node";
public static final String DB_AUTO_CLEAN_HISTORY_MESSAGES = "db.auto_clean_history_messages";
public static final String SENSITIVE_Filter_Type = "sensitive.filter.type";
@@ -116,10 +126,6 @@ public final class BrokerConstants {
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification";
public static final String MONGODB_Client_URI = "mongodb.client_uri";
public static final String MONGODB_Database = "mongodb.database";
public static final String MONGODB_Data_Expire_Days = "mongodb.data_expire_days";
public static final String MESSAGE_ROAMING = "message.roaming";
public static final String MESSAGE_Remote_History_Message = "message.remote_history_message";
@@ -140,6 +146,13 @@ public final class BrokerConstants {
public static final String CHATROOM_Participant_Idle_Time = "chatroom.participant_idle_time";
public static final String CHATROOM_Rejoin_When_Active = "chatroom.rejoin_when_active";
public static final String GROUP_Allow_Client_Custom_Operation_Notification = "group.allow_client_custom_operation_notification";
public static final String GROUP_Visible_Quit_Kickoff_Notification = "group.visible_quit_or_kickoff_notification";
public static final String USER_HIDE_PROPERTIES = "user.hide_properties";
public static final String MESSAGES_FORBIDDEN_CLIENT_SEND_TYPES = "message.forbidden_client_send_types";
public static final String MESSAGES_DISABLE_REMOTE_SEARCH = "message.disable_remote_search";
public static final String MESSAGES_RECALL_TIME_LIMIT = "message.recall_time_limit";
@@ -23,7 +23,7 @@ public class AddFriendHandler extends GroupHandler<WFCMessage.AddFriendRequest>
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.AddFriendRequest request, Qos1PublishHandler.IMCallback callback) {
long[] head = new long[1];
ErrorCode errorCode = m_messagesStore.saveAddFriendRequest(fromUser, request, head);
ErrorCode errorCode = m_messagesStore.saveAddFriendRequest(fromUser, request, head, isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
WFCMessage.User user = m_messagesStore.getUserInfo(request.getTargetUid());
if (user != null && user.getType() == ProtoConstants.UserType.UserType_Normal) {
@@ -27,9 +27,15 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
return ErrorCode.ERROR_CODE_GROUP_ALREADY_EXIST;
}
}
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), isAdmin);
if (groupInfo != null) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").getCreateGroupNotifyContent();
@@ -29,8 +29,12 @@ public class DismissGroupHandler extends GroupHandler<WFCMessage.DismissGroupReq
} else if (isAdmin || (groupInfo.getType() == ProtoConstants.GroupType.GroupType_Normal || groupInfo.getType() == ProtoConstants.GroupType.GroupType_Restricted)
&& groupInfo.getOwner() != null && groupInfo.getOwner().equals(fromUser)) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
//send notify message first, then dismiss group
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, null, "").getDismissGroupNotifyContent();
@@ -22,7 +22,7 @@ public class GetUserInfoHandler extends IMHandler<WFCMessage.PullUserRequest> {
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.PullUserRequest request, Qos1PublishHandler.IMCallback callback) {
WFCMessage.PullUserResult.Builder resultBuilder = WFCMessage.PullUserResult.newBuilder();
ErrorCode errorCode = m_messagesStore.getUserInfo(request.getRequestList(), resultBuilder);
ErrorCode errorCode = m_messagesStore.getUserInfo(fromUser, request.getRequestList(), resultBuilder);
if (errorCode == ERROR_CODE_SUCCESS) {
byte[] data = resultBuilder.build().toByteArray();
ackPayload.ensureWritable(data.length).writeBytes(data);
@@ -13,10 +13,15 @@ import cn.wildfirechat.proto.WFCMessage;
import win.liyufan.im.MessageShardingUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
abstract public class GroupHandler<T> extends IMHandler<T> {
protected void sendGroupNotification(String fromUser, String targetId, List<Integer> lines, WFCMessage.MessageContent content) {
sendGroupNotification(fromUser, targetId, lines, content, null);
}
protected void sendGroupNotification(String fromUser, String targetId, List<Integer> lines, WFCMessage.MessageContent content, Collection<String> toUsers) {
if (lines == null) {
lines = new ArrayList<>();
} else {
@@ -32,10 +37,13 @@ abstract public class GroupHandler<T> extends IMHandler<T> {
WFCMessage.Message.Builder builder = WFCMessage.Message.newBuilder().setContent(content).setServerTimestamp(timestamp);
builder.setConversation(builder.getConversationBuilder().setType(ProtoConstants.ConversationType.ConversationType_Group).setTarget(targetId).setLine(line));
builder.setFromUser(fromUser);
if(toUsers != null && !toUsers.isEmpty()) {
builder.addAllTo(toUsers);
}
try {
long messageId = MessageShardingUtil.generateId();
builder.setMessageId(messageId);
saveAndPublish(fromUser, null, builder.build(), false);
saveAndPublish(fromUser, null, builder.build());
} catch (Exception e) {
e.printStackTrace();
}
@@ -37,7 +37,7 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
long timestamp = System.currentTimeMillis();
builder.setMessageId(messageId);
builder.setServerTimestamp(timestamp);
saveAndPublish(request.getTargetUid(), null, builder.build(), false);
saveAndPublish(request.getTargetUid(), null, builder.build());
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
String language = "zh_CN";
@@ -60,7 +60,7 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
messageId = MessageShardingUtil.generateId();
builder.setMessageId(messageId);
saveAndPublish(request.getTargetUid(), null, builder.build(), false);
saveAndPublish(request.getTargetUid(), null, builder.build());
if (m_messagesStore.isNewFriendWelcomeMessage()) {
contentBuilder.setType(93);
@@ -73,16 +73,15 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
builder.setMessageId(messageId);
timestamp = System.currentTimeMillis();
builder.setServerTimestamp(timestamp);
saveAndPublish(request.getTargetUid(), null, builder.build(), false);
saveAndPublish(request.getTargetUid(), null, builder.build());
} catch (Exception e) {
e.printStackTrace();
}
if (request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted || isAdmin) {
publisher.publishNotification(IMTopic.NotifyFriendTopic, request.getTargetUid(), heads[0]);
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[1]);
}
}
if (request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted || isAdmin) {
publisher.publishNotification(IMTopic.NotifyFriendTopic, request.getTargetUid(), heads[0]);
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[1]);
}
}
return errorCode;
@@ -34,10 +34,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.*;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_OVER_FREQUENCY;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
@@ -239,17 +236,17 @@ abstract public class IMHandler<T> {
Set<String> notifyReceivers = new LinkedHashSet<>();
WFCMessage.Message.Builder messageBuilder = message.toBuilder();
int pullType = m_messagesStore.getNotifyReceivers(username, messageBuilder, notifyReceivers, false);
int pullType = m_messagesStore.getNotifyReceivers(username, messageBuilder, notifyReceivers);
mServer.getImBusinessScheduler().execute(() -> this.publisher.publish2Receivers(messageBuilder.build(), notifyReceivers, clientID, pullType));
return notifyReceivers.size();
}
protected long saveAndPublish(String username, String clientID, WFCMessage.Message message, boolean ignoreMsg) {
protected long saveAndPublish(String username, String clientID, WFCMessage.Message message) {
Set<String> notifyReceivers = new LinkedHashSet<>();
message = m_messagesStore.storeMessage(username, clientID, message);
WFCMessage.Message.Builder messageBuilder = message.toBuilder();
int pullType = m_messagesStore.getNotifyReceivers(username, messageBuilder, notifyReceivers, ignoreMsg);
int pullType = m_messagesStore.getNotifyReceivers(username, messageBuilder, notifyReceivers);
mServer.getImBusinessScheduler().execute(() -> this.publisher.publish2Receivers(messageBuilder.build(), notifyReceivers, clientID, pullType));
return notifyReceivers.size();
}
@@ -268,4 +265,13 @@ abstract public class IMHandler<T> {
mServer.getImBusinessScheduler().execute(() -> publisher.publish2Receivers(updatedMessage, notifyReceivers, clientID, ProtoConstants.PullType.Pull_Normal));
return notifyReceivers.size();
}
protected long publishRecallMultiCastMsg(long messageUid, List<String> receivers) {
WFCMessage.Message updatedMessage = m_messagesStore.getMessage(messageUid);
Set<String> notifyReceivers = new HashSet<>(receivers);
LOG.info("Multicast recall receiver count: {}", notifyReceivers.size());
mServer.getImBusinessScheduler().execute(() -> publisher.publish2Receivers(updatedMessage, notifyReceivers, null, ProtoConstants.PullType.Pull_Normal));
return notifyReceivers.size();
}
}
@@ -14,6 +14,9 @@ import cn.wildfirechat.pojos.GroupNotificationBinaryContent;
import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import cn.wildfirechat.common.ErrorCode;
import java.util.Set;
import static win.liyufan.im.IMTopic.KickoffGroupMemberTopic;
@Handler(value = KickoffGroupMemberTopic)
@@ -47,13 +50,24 @@ public class KickoffGroupMember extends GroupHandler<WFCMessage.RemoveGroupMembe
if (!isAllow && (groupInfo.getType() == ProtoConstants.GroupType.GroupType_Normal || groupInfo.getType() == ProtoConstants.GroupType.GroupType_Restricted)) {
errorCode = ErrorCode.ERROR_CODE_NOT_RIGHT;
} else {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
//send notify message first, then kickoff the member
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getRemovedMemberList()).getKickokfMemberGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
}
if((m_messagesStore.getVisibleQuitKickoffNotification() & 0x02) > 0) {
Set<String> toUsers = m_messagesStore.getGroupManagers(request.getGroupId(), true);
toUsers.addAll(request.getRemovedMemberList());
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getRemovedMemberList()).getKickokfMemberVisibleGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content, toUsers);
}
errorCode = m_messagesStore.kickoffGroupMembers(fromUser, isAdmin, request.getGroupId(), request.getRemovedMemberList());
}
}
@@ -21,9 +21,13 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
public class ModifyGroupAliasHandler extends GroupHandler<WFCMessage.ModifyGroupMemberAlias> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupMemberAlias request, Qos1PublishHandler.IMCallback callback) {
ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias());
if (errorCode == ERROR_CODE_SUCCESS && request.hasNotifyContent()) {
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias(), null, isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getAlias(), "").getModifyGroupMemberAliasNotifyContent();
@@ -22,9 +22,13 @@ import static win.liyufan.im.IMTopic.ModifyGroupInfoTopic;
public class ModifyGroupInfoHandler extends GroupHandler<WFCMessage.ModifyGroupInfoRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupInfoRequest request, Qos1PublishHandler.IMCallback callback) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode= m_messagesStore.modifyGroupInfo(fromUser, request.getGroupId(), request.getType(), request.getValue(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = null;
@@ -0,0 +1,39 @@
/*
* 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.pojos.GroupNotificationBinaryContent;
import cn.wildfirechat.proto.WFCMessage;
import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import win.liyufan.im.IMTopic;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
@Handler(IMTopic.ModifyGroupMemberAliasTopic)
public class ModifyGroupMemberAliasHandler extends GroupHandler<WFCMessage.ModifyGroupMemberAlias> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupMemberAlias request, Qos1PublishHandler.IMCallback callback) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias(), request.getMemberId(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS && request.hasNotifyContent()) {
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getAlias(), request.getMemberId()).getModifyGroupMemberAliasNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
}
}
return errorCode;
}
}
@@ -14,20 +14,32 @@ import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import cn.wildfirechat.common.ErrorCode;
import java.util.Set;
import static win.liyufan.im.IMTopic.QuitGroupTopic;
@Handler(value = QuitGroupTopic)
public class QuitGroupHandler extends GroupHandler<WFCMessage.QuitGroupRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.QuitGroupRequest request, Qos1PublishHandler.IMCallback callback) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.quitGroup(fromUser, request.getGroupId());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getQuitGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
}
if((m_messagesStore.getVisibleQuitKickoffNotification() & 0x01) > 0) {
Set<String> toUsers = m_messagesStore.getGroupManagers(request.getGroupId(), true);
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getQuitVisibleGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content, toUsers);
}
}
return errorCode;
}
@@ -0,0 +1,36 @@
/*
* 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 io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import win.liyufan.im.IMTopic;
@Handler(value = IMTopic.RecallMultiCastMessageTopic)
public class RecallMultiCastMessageHandler extends IMHandler<WFCMessage.RecallMultiCastMessageRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.RecallMultiCastMessageRequest request, Qos1PublishHandler.IMCallback callback) {
if (!isAdmin) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.recallCastMessage(request.getMessageId(), fromUser);
if(errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
return errorCode;
}
publishRecallMultiCastMsg(request.getMessageId(), request.getReceiverList());
return errorCode;
}
}
@@ -10,6 +10,7 @@ package io.moquette.imhandler;
import cn.wildfirechat.proto.WFCMessage;
import com.hazelcast.core.Member;
import io.moquette.persistence.MemorySessionStore;
import io.moquette.spi.ClientSession;
import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
@@ -24,6 +25,19 @@ import static io.moquette.BrokerConstants.HZ_Cluster_Node_External_Short_Port;
public class RouteHandler extends IMHandler<WFCMessage.RouteRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.RouteRequest request, Qos1PublishHandler.IMCallback callback) {
MemorySessionStore.Session session = m_sessionsStore.sessionForClientAndUser(fromUser, clientID);
if (session == null) {
ErrorCode errorCode = m_sessionsStore.loadActiveSession(fromUser, clientID);
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
return errorCode;
}
session = m_sessionsStore.sessionForClientAndUser(fromUser, clientID);
}
if (session == null || session.getDeleted() > 0) {
return ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH;
}
Member member = mServer.getHazelcastInstance().getCluster().getLocalMember();
String serverIp = member.getStringAttribute(HZ_Cluster_Node_External_IP);
String longPort = member.getStringAttribute(HZ_Cluster_Node_External_Long_Port);
@@ -58,9 +58,14 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
boolean ignoreMsg = false;
if (!isAdmin) { //admin do not check the right
// 不能在端上直接发送撤回和群通知
if (message.getContent().getType() == 80 || (message.getContent().getType() >= 100 && message.getContent().getType() < 200)) {
if (message.getContent().getType() == 80 || message.getContent().getType() == 81 || (message.getContent().getType() >= 100 && message.getContent().getType() < 200)) {
return ErrorCode.INVALID_PARAMETER;
}
if(m_messagesStore.getClientForbiddenSendTypes().contains(message.getContent().getType())) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
int userStatus = m_messagesStore.getUserStatus(fromUser);
if (userStatus == ProtoConstants.UserStatus.Muted || userStatus == ProtoConstants.UserStatus.Forbidden) {
return ErrorCode.ERROR_CODE_FORBIDDEN_SEND_MSG;
@@ -113,7 +118,6 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
publisher.forwardMessage(message, mForwardUrl);
}
if (!isAdmin) {
Set<String> matched = m_messagesStore.handleSensitiveWord(message.getContent().getSearchableContent());
if (matched != null && !matched.isEmpty()) {
@@ -127,7 +131,6 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
for (String word : matched) {
text = text.replace(word, "***");
}
message = message.toBuilder().setContent(message.getContent().toBuilder().setSearchableContent(text).build()).build();
} else if(mSensitiveType == 3) {
@@ -136,7 +139,9 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
}
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
saveAndPublish(fromUser, clientID, message, ignoreMsg);
if(!ignoreMsg) {
saveAndPublish(fromUser, clientID, message);
}
ackPayload = ackPayload.capacity(20);
ackPayload.writeLong(messageId);
ackPayload.writeLong(timestamp);
@@ -21,9 +21,13 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
public class SetGroupManagerHandler extends GroupHandler<WFCMessage.SetGroupManagerRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.SetGroupManagerRequest request, Qos1PublishHandler.IMCallback callback) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.setGroupManager(fromUser, request.getGroupId(), request.getType(), request.getUserIdList(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getType() + "", request.getUserIdList()).getSetGroupManagerNotifyContent();
@@ -21,9 +21,13 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
public class TransferGroupHandler extends GroupHandler<WFCMessage.TransferGroupRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.TransferGroupRequest request, Qos1PublishHandler.IMCallback callback) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
ErrorCode errorCode = m_messagesStore.transferGroup(fromUser, request.getGroupId(), request.getNewOwner(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getNewOwner()).getTransferGroupNotifyContent();
@@ -8,6 +8,7 @@
package io.moquette.persistence;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.pojos.SystemSettingPojo;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
@@ -32,6 +33,7 @@ import java.util.*;
import java.util.function.Function;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*;
@@ -72,7 +74,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -106,7 +108,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -146,7 +148,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -203,10 +205,9 @@ public class DatabaseStore {
}
if (page > 0) {
sql += "offset = '" + page * 20 + "'";
sql += " offset " + page * 20;
}
statement = connection.prepareStatement(sql);
int index = 1;
@@ -286,7 +287,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -310,7 +311,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -368,7 +369,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -424,7 +425,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -483,7 +484,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -556,7 +557,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -607,7 +608,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -668,10 +669,10 @@ public class DatabaseStore {
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} catch (IOException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
try {
if (resultSet!=null) {
@@ -679,14 +680,14 @@ public class DatabaseStore {
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, null);
}
@@ -724,7 +725,7 @@ public class DatabaseStore {
}
} catch (SQLException | IOException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, resultSet);
}
@@ -744,7 +745,7 @@ public class DatabaseStore {
LOG.info("Update rows {}", count);
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -755,14 +756,22 @@ public class DatabaseStore {
long[] before = new long[1];
before[0] = beforeUid;
boolean hasMore = loadRemoteMessagesFromTable(user, conversation, before, count, MessageShardingUtil.getMessageTable(beforeUid), messages);
if (messages.size() < count) {
if (hasMore) {
loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), MessageShardingUtil.getMessageTable(beforeUid), messages);
} else {
String nexTable = MessageShardingUtil.getPreviousMessageTable(before[0]);
if (!StringUtil.isNullOrEmpty(nexTable)) {
loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), nexTable, messages);
}
while (messages.size() < count && hasMore) {
hasMore = loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), MessageShardingUtil.getMessageTable(beforeUid), messages);
}
int month = 0;
while (messages.size() < count && !DBUtil.IsEmbedDB && month++ < 24) {
String nexTable = MessageShardingUtil.getMessageTable(beforeUid, -month);
int size = messages.size();
hasMore = true;
while (size == messages.size() && hasMore) {
hasMore = loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), nexTable, messages);
}
if (size < messages.size()) {
break;
}
}
@@ -843,7 +852,7 @@ public class DatabaseStore {
}
} catch (SQLException | IOException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, resultSet);
}
@@ -869,7 +878,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -897,12 +906,12 @@ public class DatabaseStore {
statement = null;
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -941,7 +950,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -978,7 +987,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1003,7 +1012,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1051,11 +1060,15 @@ public class DatabaseStore {
out.add(builder.build());
}
if (out.isEmpty()) {
WFCMessage.UserSettingEntry.Builder builder = WFCMessage.UserSettingEntry.newBuilder().setScope(999).setKey("").setValue("").setUpdateDt(0);
out.add(builder.build());
}
return out;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -1092,7 +1105,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1123,7 +1136,6 @@ public class DatabaseStore {
"`_type` = ?," +
"`_extra` = ?," +
"`_dt` = ?," +
"`_member_count` = ?," +
"`_mute` = ?" +
", `_join_type` = ?" +
", `_private_chat` = ?" +
@@ -1154,7 +1166,6 @@ public class DatabaseStore {
statement.setInt(index++, groupInfo.getType());
statement.setString(index++, groupInfo.getExtra());
statement.setLong(index++, groupInfo.getUpdateDt() == 0 ? System.currentTimeMillis() : groupInfo.getUpdateDt());
statement.setInt(index++, groupInfo.getMemberCount());
statement.setInt(index++, groupInfo.getMute());
statement.setInt(index++, groupInfo.getJoinType());
statement.setInt(index++, groupInfo.getPrivateChat());
@@ -1165,7 +1176,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1208,7 +1219,7 @@ public class DatabaseStore {
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, resultSet);
}
@@ -1230,7 +1241,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1270,7 +1281,7 @@ public class DatabaseStore {
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, resultSet);
}
@@ -1303,7 +1314,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1342,7 +1353,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1370,7 +1381,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1397,7 +1408,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1488,7 +1499,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1538,7 +1549,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1579,7 +1590,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1592,12 +1603,10 @@ public class DatabaseStore {
ResultSet rs = null;
try {
connection = DBUtil.getConnection();
String sql = "select `_gid` from t_group_member where `_mid` = ? and `_type` <> ?";
String sql = "select `_gid` from t_group_member where `_mid` = ? and `_type` <> 4";
statement = connection.prepareStatement(sql);
statement.setString(1, userId);
statement.setInt(2, ProtoConstants.GroupMemberType.GroupMemberType_Removed);
rs = statement.executeQuery();
Set<String> out = new HashSet<>();
@@ -1609,31 +1618,23 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
return null;
}
void updateGroupMemberCountDt(final String groupId, final int count, final long dt) {
void updateGroupMemberDt(final String groupId, final long dt) {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
String sql ;
if (count >= 0) {
sql = "update t_group set `_member_count` = ?, `_member_dt` = ? , `_dt` = ? where `_gid` = ?";
} else {
sql = "update t_group set `_member_dt` = ?, `_dt` = ? where `_gid` = ?";
}
String sql = "update t_group set `_member_dt` = ?, `_dt` = ? where `_gid` = ?";
statement = connection.prepareStatement(sql);
int index = 1;
if (count >=0) {
statement.setInt(index++, count);
}
statement.setLong(index++, dt);
statement.setLong(index++, dt);
statement.setString(index++, groupId);
@@ -1643,7 +1644,30 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
}
void updateGroupMemberCountDt(final String groupId) {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
String sql = "update t_group set `_member_count` = (select count(*) from t_group_member where `_gid` = ? and `_type` <> 4 limit 1), `_dt` = ?, `_member_dt` = `_member_dt` + 1 where `_gid` = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, groupId);
statement.setLong(2, System.currentTimeMillis());
statement.setString(3, groupId);
int c = statement.executeUpdate();
LOG.info("Update rows {}", c);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1702,7 +1726,7 @@ public class DatabaseStore {
}
}
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1711,11 +1735,8 @@ public class DatabaseStore {
int removeGroupMember(String groupId, List<String> groupMembers) {
Connection connection = null;
PreparedStatement statement = null;
PreparedStatement statement2 = null;
try {
connection = DBUtil.getConnection();
connection.setAutoCommit(false);
StringBuilder sqlBuilder = new StringBuilder("update t_group_member set `_type` = ?, `_dt` = ? where `_mid` in (");
for (int i = 0; i < groupMembers.size(); i++) {
sqlBuilder.append("?");
@@ -1724,9 +1745,7 @@ public class DatabaseStore {
}
}
sqlBuilder.append(")");
sqlBuilder.append(" and _gid = ?");
statement = connection.prepareStatement(sqlBuilder.toString());
int index = 1;
@@ -1738,36 +1757,14 @@ public class DatabaseStore {
statement.setString(index++, memberId);
}
statement.setString(index++, groupId);
int count = statement.executeUpdate();
LOG.info("Update rows {}", count);
String sql = "update t_group set `_member_count` = `_member_count` - ?, `_member_dt` = ? , `_dt` = ? where `_gid` = ?";
statement2 = connection.prepareStatement(sql);
index = 1;
statement2.setInt(index++, count);
statement2.setLong(index++, current);
statement2.setLong(index++, current);
statement2.setString(index++, groupId);
statement2.executeUpdate();
connection.commit();
connection.setAutoCommit(true);
} catch (SQLException e) {
// TODO Auto-generated catch block
if (connection != null) {
try {
connection.commit();
connection.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
DBUtil.closeDB(connection, statement2);
}
return 0;
}
@@ -1851,7 +1848,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -1903,7 +1900,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1927,7 +1924,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -1993,7 +1990,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -2027,7 +2024,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2050,7 +2047,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2072,7 +2069,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2128,7 +2125,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -2180,12 +2177,39 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
});
}
boolean isUidAndNameConflict(String uid, String name) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
long start = System.currentTimeMillis();
try {
connection = DBUtil.getConnection();
String sql = "select _uid from t_user where _name = ? and _uid <> ? limit 1";
statement = connection.prepareStatement(sql);
statement.setString(1, name);
statement.setString(2, uid);
rs = statement.executeQuery();
if (rs.next()) {
String conflictId = rs.getString(1);
LOG.error("user {} already have name {} !!!", conflictId, name);
return true;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
return false;
}
void updateUser(final WFCMessage.User user) throws Exception {
LOG.info("Database update user info {} {}", user.getUid(), user.getUpdateDt());
@@ -2260,7 +2284,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
throw new Exception(e.getMessage());
} finally {
DBUtil.closeDB(connection, statement);
@@ -2281,7 +2305,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2316,7 +2340,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2341,7 +2365,7 @@ public class DatabaseStore {
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
}
statement = connection.prepareStatement(sql);
@@ -2356,7 +2380,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
return -1;
} finally {
DBUtil.closeDB(connection, statement, rs);
@@ -2439,6 +2463,8 @@ public class DatabaseStore {
builder.setDeleted(deleted);
long longValue = rs.getLong(index++);
if(longValue <= 0)
longValue = 1;
builder.setUpdateDt(longValue);
return builder.build();
@@ -2446,7 +2472,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -2469,7 +2495,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -2492,7 +2518,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -2520,7 +2546,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -2557,7 +2583,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -2582,7 +2608,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2604,7 +2630,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2673,7 +2699,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -2703,7 +2729,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2742,7 +2768,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2781,7 +2807,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2802,7 +2828,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2823,7 +2849,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2890,7 +2916,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2913,7 +2939,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -2993,7 +3019,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -3041,7 +3067,7 @@ public class DatabaseStore {
}
}
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -3072,7 +3098,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -3107,10 +3133,9 @@ public class DatabaseStore {
if (page > 0) {
sql += "offset = '" + page * 20 + "'";
sql += " offset " + page * 20;
}
statement = connection.prepareStatement(sql);
int index = 1;
if (buzzy) {
@@ -3159,7 +3184,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -3203,7 +3228,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -3230,7 +3255,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
@@ -3254,7 +3279,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
@@ -3277,7 +3302,7 @@ public class DatabaseStore {
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e);
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
File diff suppressed because it is too large Load Diff
@@ -57,6 +57,8 @@ public class MemorySessionStore implements ISessionsStore {
private int deleted;
private boolean pullHistoryMsg;
public int getDeleted() {
return deleted;
}
@@ -139,6 +141,14 @@ public class MemorySessionStore implements ISessionsStore {
this.carrierName = carrierName;
}
public boolean isPullHistoryMsg() {
return pullHistoryMsg;
}
public void setPullHistoryMsg(boolean pullHistoryMsg) {
this.pullHistoryMsg = pullHistoryMsg;
}
public long getUpdateDt() {
return updateDt;
}
@@ -339,18 +349,22 @@ public class MemorySessionStore implements ISessionsStore {
Session session = sessions.get(clientID);
if (session != null && !session.username.equals(username)) {
if (userSessions.get(username) != null) {
userSessions.get(username).remove(clientID);
if (userSessions.get(session.username) != null) {
userSessions.get(session.username).remove(clientID);
}
session = null;
}
ClientSession clientSession = new ClientSession(clientID, this);
session = databaseStore.getSession(username, clientID, clientSession);
if (session == null) {
session = databaseStore.createSession(username, clientID, clientSession, platform);
if(session == null) {
session = databaseStore.getSession(username, clientID, clientSession);
if (session == null) {
session = databaseStore.createSession(username, clientID, clientSession, platform);
}
}
sessions.put(clientID, session);
sessions.put(clientID, session);
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
sessionSet.add(clientID);
if (session.getDeleted() > 0) {
session.setDeleted(0);
@@ -393,8 +407,8 @@ public class MemorySessionStore implements ISessionsStore {
if (remove) {
sessions.remove(c);
mServer.getProcessor().kickoffSession(s);
it.remove();
mServer.getProcessor().kickoffSession(s);
}
}
}
@@ -405,6 +419,34 @@ public class MemorySessionStore implements ISessionsStore {
return session;
}
@Override
public void kickoffUserClient(String username, String cid) {
List<String> clientIds = new ArrayList<>();
if(StringUtil.isNullOrEmpty(cid)) {
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
clientIds.addAll(sessionSet);
} else {
clientIds.add(cid);
}
for (String clientID: clientIds) {
Session session = sessions.get(clientID);
if(session == null) {
ClientSession clientSession = new ClientSession(clientID, this);
session = databaseStore.getSession(username, clientID, clientSession);
if (session == null || session.getDeleted() > 0) {
continue;
}
sessions.put(clientID, session);
}
if (session.getDeleted() == 0) {
session.setDeleted(1);
databaseStore.updateSessionDeleted(username, clientID, 1);
mServer.getProcessor().kickoffSession(session);
}
}
}
@Override
public ErrorCode loadActiveSession(String username, String clientID) {
@@ -452,7 +494,6 @@ public class MemorySessionStore implements ISessionsStore {
session.setUsername(username);
sessions.put(clientID, session);
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
sessionSet.add(clientID);
@@ -491,11 +532,15 @@ public class MemorySessionStore implements ISessionsStore {
@Override
public void loadUserSession(String username, String clientID) {
if (sessions.containsKey(clientID)) {
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
sessionSet.add(clientID);
return;
}
Session session = databaseStore.getSession(username, clientID, new ClientSession(clientID, this));
if (session != null) {
sessions.put(clientID, session);
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
sessionSet.add(clientID);
}
}
@@ -94,6 +94,7 @@ public class Server {
private ThreadPoolExecutorWrapper dbScheduler;
private ThreadPoolExecutorWrapper imBusinessScheduler;
private ThreadPoolExecutorWrapper callbackScheduler;
private IConfig mConfig;
@@ -225,7 +226,7 @@ public class Server {
handlers = Collections.emptyList();
}
DBUtil.init(config);
String strKey = config.getProperty(BrokerConstants.CLIENT_PROTO_SECRET_KEY);
String strKey = "0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F";
String[] strs = strKey.split(",");
if(strs.length != 16) {
LOG.error("Key error, it length should be 16");
@@ -243,6 +244,7 @@ public class Server {
int threadNum = Runtime.getRuntime().availableProcessors() * 2;
dbScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(threadNum), threadNum, "db");
imBusinessScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(threadNum), threadNum, "business");
callbackScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(1), 1, "callback");
final String handlerProp = System.getProperty(BrokerConstants.INTERCEPT_HANDLER_PROPERTY_NAME);
if (handlerProp != null) {
@@ -251,6 +253,9 @@ public class Server {
initMediaServerConfig(config);
String monitorEventAddress = config.getProperty(MONITOR_Exception_Event_Address);
Utility.setMonitorEventAddress(monitorEventAddress);
final String persistencePath = config.getProperty(BrokerConstants.PERSISTENT_STORE_PROPERTY_NAME);
LOG.info("Configuring Using persistent store file, path={}", persistencePath);
m_store = initStore(config, this);
@@ -431,6 +436,7 @@ public class Server {
System.out.println("Server will flush data to db before shutting down, please wait 5 seconds!");
LOG.info("Unbinding server from the configured ports");
m_shutdowning = true;
DBUtil.SystemExiting = true;
m_acceptor.close();
LOG.trace("Stopping MQTT protocol processor");
@@ -447,6 +453,7 @@ public class Server {
dbScheduler.shutdown();
imBusinessScheduler.shutdown();
callbackScheduler.shutdown();
LOG.info("Moquette server has been stopped.");
}
@@ -507,4 +514,8 @@ public class Server {
public ThreadPoolExecutorWrapper getImBusinessScheduler() {
return imBusinessScheduler;
}
public ThreadPoolExecutorWrapper getCallbackScheduler() {
return callbackScheduler;
}
}
@@ -35,10 +35,6 @@ public abstract class IConfig {
void assignDefaults() {
setProperty(BrokerConstants.PORT_PROPERTY_NAME, Integer.toString(BrokerConstants.PORT));
setProperty(BrokerConstants.HOST_PROPERTY_NAME, BrokerConstants.HOST);
// setProperty(BrokerConstants.WEB_SOCKET_PORT_PROPERTY_NAME,
// Integer.toString(BrokerConstants.WEBSOCKET_PORT));
// setProperty(BrokerConstants.PERSISTENT_STORE_PROPERTY_NAME,
// BrokerConstants.DEFAULT_PERSISTENT_PATH);
setProperty(BrokerConstants.AUTHORIZATOR_CLASS_NAME, "");
}
@@ -33,19 +33,6 @@ public class MemoryConfig extends IConfig {
}
}
// private void createDefaults() {
// m_properties.put(BrokerConstants.PORT_PROPERTY_NAME, Integer.toString(BrokerConstants.PORT));
// m_properties.put(BrokerConstants.HOST_PROPERTY_NAME, BrokerConstants.HOST);
// m_properties.put(BrokerConstants.WEB_SOCKET_PORT_PROPERTY_NAME,
// Integer.toString(BrokerConstants.WEBSOCKET_PORT));
// m_properties.put(BrokerConstants.PASSWORD_FILE_PROPERTY_NAME, "");
// m_properties.put(BrokerConstants.PERSISTENT_STORE_PROPERTY_NAME,
// BrokerConstants.DEFAULT_PERSISTENT_PATH);
// m_properties.put(BrokerConstants.ALLOW_ANONYMOUS_PROPERTY_NAME, true);
// m_properties.put(BrokerConstants.AUTHENTICATOR_CLASS_NAME, "");
// m_properties.put(BrokerConstants.AUTHORIZATOR_CLASS_NAME, "");
// }
@Override
public void setProperty(String name, String value) {
m_properties.setProperty(name, value);
@@ -49,6 +49,7 @@ import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.io.IOException;
import java.net.BindException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@@ -57,35 +58,6 @@ import static io.netty.channel.ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE;
public class NettyAcceptor implements ServerAcceptor {
private static final String MQTT_SUBPROTOCOL_CSV_LIST = "mqtt, mqttv3.1, mqttv3.1.1";
static class WebSocketFrameToByteBufDecoder extends MessageToMessageDecoder<BinaryWebSocketFrame> {
@Override
protected void decode(ChannelHandlerContext chc, BinaryWebSocketFrame frame, List<Object> out)
throws Exception {
// convert the frame to a ByteBuf
ByteBuf bb = frame.content();
// System.out.println("WebSocketFrameToByteBufDecoder decode - " +
// ByteBufUtil.hexDump(bb));
bb.retain();
out.add(bb);
}
}
static class ByteBufToWebSocketFrameEncoder extends MessageToMessageEncoder<ByteBuf> {
@Override
protected void encode(ChannelHandlerContext chc, ByteBuf bb, List<Object> out) throws Exception {
// convert the ByteBuf to a WebSocketFrame
BinaryWebSocketFrame result = new BinaryWebSocketFrame();
// System.out.println("ByteBufToWebSocketFrameEncoder encode - " +
// ByteBufUtil.hexDump(bb));
result.content().writeBytes(bb);
out.add(result);
}
}
abstract class PipelineInitializer {
abstract void init(ChannelPipeline pipeline) throws Exception;
@@ -144,17 +116,6 @@ public class NettyAcceptor implements ServerAcceptor {
this.errorsCather = Optional.empty();
initializePlainTCPTransport(mqttHandler, props);
String sslTcpPortProp = props.getProperty(BrokerConstants.SSL_PORT_PROPERTY_NAME);
String wssPortProp = props.getProperty(BrokerConstants.WSS_PORT_PROPERTY_NAME);
if (sslTcpPortProp != null || wssPortProp != null) {
SSLContext sslContext = sslCtxCreator.initSSLContext();
if (sslContext == null) {
LOG.error("Can't initialize SSLHandler layer! Exiting, check your configuration of jks");
return;
}
initializeSSLTCPTransport(mqttHandler, props, sslContext);
initializeWSSTransport(mqttHandler, props, sslContext);
}
}
private void initFactory(String host, int port, String protocol, final PipelineInitializer pipeliner) {
@@ -187,6 +148,11 @@ public class NettyAcceptor implements ServerAcceptor {
f.sync().addListener(FIRE_EXCEPTION_ON_FAILURE);
} catch (InterruptedException ex) {
LOG.error("An interruptedException was caught while initializing server. Protocol={}", protocol, ex);
} catch (Exception e) {
e.printStackTrace();
LOG.error("端口 {} 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep {}", port, port);
System.out.println("端口 " + port + " 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep " + port);
System.exit(-1);
}
}
@@ -225,81 +191,6 @@ public class NettyAcceptor implements ServerAcceptor {
});
}
private void initializeSSLTCPTransport(final NettyMQTTHandler handler, IConfig props, final SSLContext sslContext)
throws IOException {
LOG.info("Configuring SSL MQTT transport");
String sslPortProp = props.getProperty(SSL_PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
if (DISABLED_PORT_BIND.equals(sslPortProp)) {
// Do nothing no SSL configured
LOG.info("Property {} has been set to {}. SSL MQTT will be disabled",
BrokerConstants.SSL_PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
return;
}
int sslPort = Integer.parseInt(sslPortProp);
LOG.info("Starting SSL on port {}", sslPort);
final MoquetteIdleTimeoutHandler timeoutHandler = new MoquetteIdleTimeoutHandler();
String host = props.getProperty(BrokerConstants.HOST_PROPERTY_NAME);
String sNeedsClientAuth = props.getProperty(BrokerConstants.NEED_CLIENT_AUTH, "false");
final boolean needsClientAuth = Boolean.valueOf(sNeedsClientAuth);
initFactory(host, sslPort, "SSL MQTT", new PipelineInitializer() {
@Override
void init(ChannelPipeline pipeline) throws Exception {
pipeline.addLast("ssl", createSslHandler(sslContext, needsClientAuth));
pipeline.addFirst("idleStateHandler", new IdleStateHandler(nettyChannelTimeoutSeconds, 0, 0));
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
// pipeline.addLast("logger", new LoggingHandler("Netty", LogLevel.ERROR));
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
pipeline.addLast("decoder", new MqttDecoder());
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
pipeline.addLast("messageLogger", new MQTTMessageLogger());
pipeline.addLast("handler", handler);
}
});
}
private void initializeWSSTransport(final NettyMQTTHandler handler, IConfig props, final SSLContext sslContext)
throws IOException {
LOG.info("Configuring secure websocket MQTT transport");
String sslPortProp = props.getProperty(WSS_PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
if (DISABLED_PORT_BIND.equals(sslPortProp)) {
// Do nothing no SSL configured
LOG.info("Property {} has been set to {}. Secure websocket MQTT will be disabled",
BrokerConstants.WSS_PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
return;
}
int sslPort = Integer.parseInt(sslPortProp);
final MoquetteIdleTimeoutHandler timeoutHandler = new MoquetteIdleTimeoutHandler();
String host = props.getProperty(BrokerConstants.HOST_PROPERTY_NAME);
String sNeedsClientAuth = props.getProperty(BrokerConstants.NEED_CLIENT_AUTH, "false");
final boolean needsClientAuth = Boolean.valueOf(sNeedsClientAuth);
initFactory(host, sslPort, "Secure websocket", new PipelineInitializer() {
@Override
void init(ChannelPipeline pipeline) throws Exception {
pipeline.addLast("ssl", createSslHandler(sslContext, needsClientAuth));
pipeline.addLast("httpEncoder", new HttpResponseEncoder());
pipeline.addLast("httpDecoder", new HttpRequestDecoder());
pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
pipeline.addLast("webSocketHandler",
new WebSocketServerProtocolHandler("/org/fusesource/mqtt", MQTT_SUBPROTOCOL_CSV_LIST));
pipeline.addLast("ws2bytebufDecoder", new WebSocketFrameToByteBufDecoder());
pipeline.addLast("bytebuf2wsEncoder", new ByteBufToWebSocketFrameEncoder());
pipeline.addFirst("idleStateHandler", new IdleStateHandler(nettyChannelTimeoutSeconds, 0, 0));
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
pipeline.addLast("decoder", new MqttDecoder());
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
pipeline.addLast("messageLogger", new MQTTMessageLogger());
pipeline.addLast("handler", handler);
}
});
}
public void close() {
LOG.info("Closing Netty acceptor...");
if (m_workerGroup == null || m_bossGroup == null) {
@@ -30,6 +30,7 @@ import io.netty.handler.codec.mqtt.MqttQoS;
import cn.wildfirechat.common.ErrorCode;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;
@@ -99,7 +100,7 @@ public interface IMessagesStore {
DatabaseStore getDatabaseStore();
WFCMessage.Message storeMessage(String fromUser, String fromClientId, WFCMessage.Message message);
void storeSensitiveMessage(WFCMessage.Message message);
int getNotifyReceivers(String fromUser, WFCMessage.Message.Builder message, Set<String> notifyReceivers, boolean ignoreMsg);
int getNotifyReceivers(String fromUser, WFCMessage.Message.Builder message, Set<String> notifyReceivers);
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);
@@ -111,7 +112,7 @@ public interface IMessagesStore {
void clearUserGroups(String userId);
ErrorCode dismissGroup(String operator, String groupId, boolean isAdmin);
ErrorCode modifyGroupInfo(String operator, String groupId, int modifyType, String value, boolean isAdmin);
ErrorCode modifyGroupAlias(String operator, String groupId, String alias);
ErrorCode modifyGroupAlias(String operator, String groupId, String alias, String memberId, boolean isAdmin);
List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests);
WFCMessage.GroupInfo getGroupInfo(String groupId);
Set<String> getUserGroupIds(String userId);
@@ -121,14 +122,18 @@ public interface IMessagesStore {
ErrorCode setGroupManager(String operator, String groupId, int type, List<String> userList, boolean isAdmin);
boolean isMemberInGroup(String member, String groupId);
ErrorCode canSendMessageInGroup(String member, String groupId);
Set<String> getGroupManagers(String groupId, boolean includeOwner);
ErrorCode recallMessage(long messageUid, String operatorId, String clientId, boolean isAdmin);
ErrorCode recallCastMessage(long messageUid, String operatorId);
void clearUserMessages(String userId);
WFCMessage.Robot getRobot(String robotId);
void addRobot(WFCMessage.Robot robot);
ErrorCode getUserInfo(List<WFCMessage.UserRequest> requestList, WFCMessage.PullUserResult.Builder builder);
ErrorCode getUserInfo(String fromUser, List<WFCMessage.UserRequest> requestList, WFCMessage.PullUserResult.Builder builder);
ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request) throws Exception;
void updateUserOnlineSetting(MemorySessionStore.Session session, boolean online);
@@ -139,6 +144,7 @@ public interface IMessagesStore {
void addUserInfo(WFCMessage.User user, String password) throws Exception;
void destoryUser(String userId);
void updateUserInfo(WFCMessage.User user) throws Exception;
WFCMessage.User getUserInfo(String userId);
WFCMessage.User getUserInfoByName(String name);
WFCMessage.User getUserInfoByMobile(String mobile);
@@ -164,7 +170,7 @@ public interface IMessagesStore {
void clearUserFriend(String userId);
List<WFCMessage.FriendRequest> getFriendRequestList(String userId, long version);
ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head);
ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin);
ErrorCode handleFriendRequest(String userId, WFCMessage.HandleFriendRequest request, WFCMessage.Message.Builder msgBuilder, long[] heads, boolean isAdmin);
boolean isNewFriendWelcomeMessage();
ErrorCode deleteFriend(String userId, String friendUid, long[] head);
@@ -184,11 +190,12 @@ public interface IMessagesStore {
List<WFCMessage.UserSettingEntry> getUserSetting(String userId, int scope);
long updateUserSettings(String userId, WFCMessage.ModifyUserSettingReq request);
void clearUserSettings(String userId);
boolean getUserGlobalSilent(String userId);
boolean getUserGlobalSlient(String userId);
boolean getUserPushHiddenDetail(String userId);
boolean getUserConversationSlient(String userId, WFCMessage.Conversation conversation);
boolean getUserConversationSilent(String userId, WFCMessage.Conversation conversation);
boolean getSilentWhenPcOnline(String userId);
boolean isUserNoDisturbing(String userId);
ErrorCode createChannel(String operator, WFCMessage.ChannelInfo channelInfo);
void clearUserChannels(String userId);
ErrorCode modifyChannelInfo(String operator, String channelId, int modifyType, String value);
@@ -206,6 +213,12 @@ public interface IMessagesStore {
List<String> getAllSensitiveWords();
WFCMessage.Message getMessage(long messageId);
boolean isAllowClientCustomGroupNotification();
int getVisibleQuitKickoffNotification();
List<Integer> getClientForbiddenSendTypes();
long getMessageHead(String user);
long getFriendHead(String user);
long getFriendRqHead(String user);
@@ -51,6 +51,8 @@ public interface ISessionsStore {
void updateSessionToken(Session session, boolean voip);
void clearUserSession(String username);
void kickoffUserClient(String userId, String clientId);
/**
* @param clientID
* the client owning the session.
@@ -25,11 +25,11 @@ import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.util.StringUtil;
import cn.wildfirechat.pojos.OutputNotifyChannelSubscribeStatus;
import cn.wildfirechat.pojos.SendMessageData;
import com.xiaoleilu.hutool.system.UserInfo;
import com.xiaoleilu.loServer.model.FriendData;
import io.moquette.persistence.*;
import io.moquette.persistence.MemorySessionStore.Session;
import io.moquette.server.ConnectionDescriptorStore;
import io.moquette.server.Server;
import io.moquette.spi.IMessagesStore;
import io.moquette.spi.ISessionsStore;
import io.netty.buffer.ByteBuf;
@@ -49,6 +49,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.BiFunction;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
public class MessagesPublisher {
@@ -161,7 +162,7 @@ public class MessagesPublisher {
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageHead, Collection<String> receivers, String pushContent, String pushData, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag) {
if (persistFlag == Transparent) {
publishTransparentMessage2Receivers(messageHead, receivers, pullType);
publishTransparentMessage2Receivers(messageHead, receivers, pullType, exceptClientId);
return;
}
@@ -176,7 +177,14 @@ public class MessagesPublisher {
message = m_messagesStore.getMessage(messageHead);
}
final WFCMessage.Message finalMsg = message;
executorCallback.execute(() -> HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(SendMessageData.fromProtoMessage(finalMsg), SendMessageData.class)));
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(SendMessageData.fromProtoMessage(finalMsg), SendMessageData.class));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
continue;
}
}
@@ -198,6 +206,23 @@ public class MessagesPublisher {
if (pullType == ProtoConstants.PullType.Pull_ChatRoom) {
targetClients = m_messagesStore.getChatroomMemberClient(user);
}
boolean isPcOnline = false;
if (!user.equals(sender)) {
for (Session targetSession : sessions) {
if (targetSession.getPlatform() == ProtoConstants.Platform.Platform_WEB
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_Windows
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_LINUX
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_OSX) {
boolean targetIsActive = this.connectionDescriptors.isConnected(targetSession.getClientSession().clientID);
if (targetIsActive) {
isPcOnline = true;
break;
}
}
}
}
for (Session targetSession : sessions) {
//超过7天不活跃的用户忽略
if(System.currentTimeMillis() - targetSession.getLastActiveTime() > 7 * 24 * 60 * 60 * 1000) {
@@ -227,11 +252,13 @@ public class MessagesPublisher {
}
}
boolean isSlient;
boolean isSilent;
boolean isConvSilent = false;
if (pullType == ProtoConstants.PullType.Pull_ChatRoom) {
isSlient = true;
isSilent = true;
isConvSilent = true;
} else {
isSlient = false;
isSilent = false;
if (!user.equals(sender)) {
WFCMessage.Conversation conversation;
@@ -241,29 +268,32 @@ public class MessagesPublisher {
conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(target).build();
}
if (m_messagesStore.getUserConversationSlient(user, conversation)) {
if (m_messagesStore.getUserConversationSilent(user, conversation)) {
LOG.info("The conversation {}-{}-{} is slient", conversation.getType(), conversation.getTarget(), conversation.getLine());
isSlient = true;
isConvSilent = true;
}
if (m_messagesStore.getUserGlobalSlient(user)) {
if (m_messagesStore.getUserGlobalSilent(user)) {
LOG.info("The user {} is global sliented", user);
isSlient = true;
isSilent = true;
}
if (!isSilent && isPcOnline && m_messagesStore.getSilentWhenPcOnline(user)) {
LOG.info("The user {} pc online and silent when pc online", user);
isSilent = true;
}
if (!isSilent && m_messagesStore.isUserNoDisturbing(user)) {
LOG.info("The user {} is no disturbing", user);
isSilent = true;
}
}
if (!StringUtil.isNullOrEmpty(pushContent) || messageContentType == 400) {
if (!isSlient && (persistFlag & 0x02) > 0) {
if (!isConvSilent && (persistFlag & 0x02) > 0) {
targetSession.setUnReceivedMsgs(targetSession.getUnReceivedMsgs() + 1);
}
}
if (isSlient) {
if (mentionType == 2 || (mentionType == 1 && mentionTargets.contains(user))) {
isSlient = false;
}
}
}
boolean needPush = !user.equals(sender);
@@ -294,15 +324,15 @@ public class MessagesPublisher {
int curMentionType = 0;
if (mentionType == 2) {
curMentionType = 2;
isSlient = false;
isConvSilent = false;
} else if (mentionType == 1){
if (mentionTargets != null && mentionTargets.contains(user)) {
curMentionType = 1;
isSlient = false;
isConvSilent = false;
}
}
if ((StringUtil.isNullOrEmpty(pushContent) && messageContentType != 402 && messageContentType != 400)) {
if ((StringUtil.isNullOrEmpty(pushContent) && messageContentType != 402 && messageContentType != 400 && messageContentType != 401)) {
LOG.info("push content is empty and contenttype is {}", messageContentType);
continue;
}
@@ -312,8 +342,13 @@ public class MessagesPublisher {
continue;
}
if (isSlient) {
LOG.info("Slient of user or conversation");
if (isConvSilent) {
LOG.info("Silent of user or conversation");
continue;
}
if (isSilent) {
LOG.info("Silent of user");
continue;
}
@@ -338,8 +373,27 @@ public class MessagesPublisher {
}
}
}
public boolean sendOfflineNotify(String clientId) {
boolean targetIsActive = this.connectionDescriptors.isConnected(clientId);
if (targetIsActive) {
ByteBuf payload = Unpooled.buffer();
payload.ensureWritable(1).writeBytes("1".getBytes());
MqttPublishMessage publishMsg;
publishMsg = notRetainedPublish(IMTopic.NotifyOffline, MqttQoS.AT_MOST_ONCE, payload);
private void publishTransparentMessage2Receivers(long messageHead, Collection<String> receivers, int pullType) {
boolean sent = this.messageSender.sendPublish(clientId, publishMsg);
if (sent) {
return true;
}
} else {
LOG.info("the target {} is not active", clientId);
}
return false;
}
private void publishTransparentMessage2Receivers(long messageHead, Collection<String> receivers, int pullType, String exceptClientId) {
WFCMessage.Message message = m_messagesStore.getMessage(messageHead);
if (message != null) {
@@ -354,6 +408,9 @@ public class MessagesPublisher {
if (targetSession.getClientID() == null) {
continue;
}
if (targetSession.getClientID().equals(exceptClientId)) {
continue;
}
boolean targetIsActive = this.connectionDescriptors.isConnected(targetSession.getClientSession().clientID);
if (targetIsActive) {
@@ -510,7 +567,14 @@ public class MessagesPublisher {
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
executorCallback.execute(() -> HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(SendMessageData.fromProtoMessage(message), SendMessageData.class)));
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(SendMessageData.fromProtoMessage(message), SendMessageData.class));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
long messageId = message.getMessageId();
@@ -550,13 +614,28 @@ public class MessagesPublisher {
}
public void forwardMessage(final WFCMessage.Message message, String forwardUrl) {
executorCallback.execute(() -> HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class)));
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
public void notifyChannelListenStatusChanged(WFCMessage.ChannelInfo channelInfo, String user, boolean listen) {
if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
return;
}
executorCallback.execute(() -> HttpUtils.httpJsonPost(channelInfo.getCallback() + "/subscribe", new Gson().toJson(new OutputNotifyChannelSubscribeStatus(user, channelInfo.getTargetId(), listen), OutputNotifyChannelSubscribeStatus.class)));
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/subscribe", new Gson().toJson(new OutputNotifyChannelSubscribeStatus(user, channelInfo.getTargetId(), listen), OutputNotifyChannelSubscribeStatus.class));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
@@ -54,6 +54,10 @@ class PersistentQueueMessageSender {
boolean sendPublish(ClientSession clientsession, MqttPublishMessage pubMessage) {
String clientId = clientsession.clientID;
return sendPublish(clientId, pubMessage);
}
boolean sendPublish(String clientId, MqttPublishMessage pubMessage) {
final int messageId = pubMessage.variableHeader().packetId();
final String topicName = pubMessage.variableHeader().topicName();
if (LOG.isDebugEnabled()) {
@@ -17,7 +17,6 @@
package io.moquette.spi.impl;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.SendMessageData;
import cn.wildfirechat.pojos.UserOnlineStatus;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
@@ -54,6 +53,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static io.moquette.spi.impl.InternalRepublisher.createPublishForQos;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
import static io.moquette.spi.impl.Utils.readBytesAndRewind;
import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.*;
import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from;
@@ -72,15 +72,30 @@ public class ProtocolProcessor {
public void kickoffSession(final MemorySessionStore.Session session) {
mServer.getImBusinessScheduler().execute(()->{
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID());
try {
if (descriptor != null) {
processDisconnect(descriptor.getChannel(), true, false);
new Thread(() -> {
messagesPublisher.sendOfflineNotify(session.getClientID());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
mServer.getImBusinessScheduler().execute(()->{
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID());
try {
if (descriptor != null) {
processDisconnect(descriptor.getChannel(), true, false);
}
} catch (InterruptedException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
m_messagesStore.updateUserOnlineSetting(session, false);
});
}).start();
});
}
@@ -252,7 +267,14 @@ public class ProtocolProcessor {
public void forwardOnlineStatusEvent(String userId, String clientId, int platform, int status, String packageName) {
if (!StringUtil.isNullOrEmpty(mUserOnlineStatusCallback)) {
executorCallback.execute(() -> HttpUtils.httpJsonPost(mUserOnlineStatusCallback, new Gson().toJson(new UserOnlineStatus(userId, clientId, platform, status, packageName))));
mServer.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mUserOnlineStatusCallback, new Gson().toJson(new UserOnlineStatus(userId, clientId, platform, status, packageName)));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
@@ -16,12 +16,10 @@
package io.moquette.spi.impl;
import static cn.wildfirechat.common.ErrorCode.*;
import static io.moquette.spi.impl.Utils.readBytesAndRewind;
import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from;
import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_NOT_IMPLEMENT;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_OVER_FREQUENCY;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -256,6 +254,13 @@ public class Qos1PublishHandler extends QosPublishHandler {
String imtopic = topic.getTopic();
ByteBuf payload = msg.payload();
byte[] payloadContent = readBytesAndRewind(payload);
if(payloadContent.length == 0) {
ByteBuf ackPayload = Unpooled.buffer();
ackPayload.ensureWritable(1).writeByte(ERROR_CODE_INVALID_DATA.getCode());
sendPubAck(clientID, messageID, ackPayload, ERROR_CODE_INVALID_DATA);
return;
}
MemorySessionStore.Session session = m_sessionStore.getSession(clientID);
payloadContent = AES.AESDecrypt(payloadContent, session.getSecret(), true);
imHandler(clientID, username, imtopic, payloadContent, (errorCode, ackPayload) -> sendPubAck(clientID, messageID, ackPayload, errorCode), false);
+255 -143
View File
@@ -14,6 +14,8 @@ import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.hazelcast.util.StringUtil;
@@ -27,6 +29,8 @@ import org.slf4j.LoggerFactory;
import java.util.concurrent.ConcurrentHashMap;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
public class DBUtil {
private static final Logger LOG = LoggerFactory.getLogger(DBUtil.class);
private static ComboPooledDataSource comboPooledDataSource = null;
@@ -39,118 +43,226 @@ public class DBUtil {
}
};
public static boolean IsEmbedDB = false;
public static boolean IsEmbedDB = false;
public static boolean SystemExiting = false;
public static boolean ClearDBDebugMode = false;
public static void init(IConfig config) {
String embedDB = config.getProperty(BrokerConstants.EMBED_DB_PROPERTY_NAME);
if (embedDB != null && embedDB.equals("1")) {
IsEmbedDB = true;
LOG.info("Use h2 database");
public static void init(IConfig config) {
String embedDB = config.getProperty(BrokerConstants.EMBED_DB_PROPERTY_NAME);
boolean autoCleanMsgs = "true".equals(config.getProperty(BrokerConstants.DB_AUTO_CLEAN_HISTORY_MESSAGES));
if (embedDB != null && embedDB.equals("1")) {
IsEmbedDB = true;
LOG.info("Use h2 database");
} else {
IsEmbedDB = false;
LOG.info("Use mysql database");
}
if (comboPooledDataSource == null) {
String migrateLocation;
if (IsEmbedDB) {
migrateLocation = "filesystem:./migrate/h2";
comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setJdbcUrl( "jdbc:h2:./h2db/wfchat;AUTO_SERVER=TRUE;MODE=MySQL" );
comboPooledDataSource.setUser("SA");
comboPooledDataSource.setPassword("SA");
comboPooledDataSource.setMinPoolSize(5);
comboPooledDataSource.setAcquireIncrement(5);
comboPooledDataSource.setMaxPoolSize(20);
comboPooledDataSource.setIdleConnectionTestPeriod(60 * 5);
comboPooledDataSource.setMinPoolSize(3);
comboPooledDataSource.setInitialPoolSize(3);
try {
comboPooledDataSource.setDriverClass( "org.h2.Driver" ); //loads the jdbc driver
} catch (PropertyVetoException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
System.exit(-1);
}
} else {
IsEmbedDB = false;
LOG.info("Use mysql database");
}
migrateLocation = "filesystem:./migrate/mysql";
comboPooledDataSource = new ComboPooledDataSource("mysql");
try {
String url01 = comboPooledDataSource.getJdbcUrl().substring(0,comboPooledDataSource.getJdbcUrl().indexOf("?"));
String datasourceName = url01.substring(url01.lastIndexOf("/")+1);
// 连接已经存在的数据库,如:mysql
String jdbc = comboPooledDataSource.getJdbcUrl().replace(datasourceName, "");
Connection connection = DriverManager.getConnection(jdbc, comboPooledDataSource.getUser(), comboPooledDataSource.getPassword());
Statement statement = connection.createStatement();
if (comboPooledDataSource == null) {
String migrateLocation;
if (IsEmbedDB) {
migrateLocation = "filesystem:./migrate/h2";
comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setJdbcUrl( "jdbc:h2:./h2db/wfchat;AUTO_SERVER=TRUE;MODE=MySQL" );
comboPooledDataSource.setUser("SA");
comboPooledDataSource.setPassword("SA");
comboPooledDataSource.setMinPoolSize(5);
comboPooledDataSource.setAcquireIncrement(5);
comboPooledDataSource.setMaxPoolSize(20);
comboPooledDataSource.setIdleConnectionTestPeriod(60 * 5);
comboPooledDataSource.setMinPoolSize(3);
comboPooledDataSource.setInitialPoolSize(3);
try {
comboPooledDataSource.setDriverClass( "org.h2.Driver" ); //loads the jdbc driver
} catch (PropertyVetoException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
System.exit(-1);
}
} else {
migrateLocation = "filesystem:./migrate/mysql";
comboPooledDataSource = new ComboPooledDataSource("mysql");
try {
String url01 = comboPooledDataSource.getJdbcUrl().substring(0,comboPooledDataSource.getJdbcUrl().indexOf("?"));
String datasourceName = url01.substring(url01.lastIndexOf("/")+1);
// 连接已经存在的数据库,如:mysql
String jdbc = comboPooledDataSource.getJdbcUrl().replace(datasourceName, "");
Connection connection = DriverManager.getConnection(jdbc, comboPooledDataSource.getUser(), comboPooledDataSource.getPassword());
Statement statement = connection.createStatement();
// 创建数据库
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS `" + datasourceName + "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
statement.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
// 创建数据库
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS `" + datasourceName + "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
statement.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
Flyway flyway = Flyway.configure().dataSource(comboPooledDataSource).locations(migrateLocation).baselineOnMigrate(true).load();
flyway.migrate();
}
Flyway flyway = Flyway.configure().dataSource(comboPooledDataSource).locations(migrateLocation).baselineOnMigrate(true).load();
flyway.migrate();
if(autoCleanMsgs) {
cleanHistoryMsg();
}
}
}
private static void cleanHistoryMsg() {
new Thread(()->{
long usedTime = 0;
while (true) {
if(SystemExiting) {
break;
}
try {
long sleepTime;
if(ClearDBDebugMode) {
sleepTime = 60 * 1000 - usedTime;
} else {
sleepTime = 60 * 60 * 1000 - usedTime;
}
if(sleepTime < 0) {
sleepTime = 5 * 1000;
}
Thread.sleep(sleepTime);
LOG.info("Start clean history messages");
if(SystemExiting) {
break;
}
long start = System.currentTimeMillis();
if(IsEmbedDB) {
clearH2DB();
} else {
clearMySQL();
}
usedTime = System.currentTimeMillis() - start;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
private static boolean sleep() {
if(SystemExiting)
return true;
try {
if(ClearDBDebugMode) {
Thread.sleep(500);
} else {
Thread.sleep(10000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return SystemExiting;
}
private static long getMaxMidNeedClean() {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.YEAR, -3);
cal.add(Calendar.DATE, 1);
return MessageShardingUtil.getMsgIdFromTimestamp(cal.getTimeInMillis());
}
private static void clearH2DB() {
clearOneTable("t_user_messages");
if(sleep()) {
return;
}
clearOneTable("t_messages");
}
private static void clearMySQL() {
for (int i = 0; i < 128; i++) {
clearOneTable("t_user_messages_" + i);
if(sleep()) {
return;
}
}
private static List<String> getCreateSql() {
List<String> out = new ArrayList<>();
try{
BufferedReader br = new BufferedReader(new FileReader("h2/create_table.sql"));//构造一个BufferedReader类来读取文件
String s = null;
StringBuilder result = new StringBuilder();
while((s = br.readLine())!=null) {
result.append(s);
if (s.contains(";")) {
out.add(result.toString());
result = new StringBuilder();
}
}
br.close();
}catch(Exception e){
e.printStackTrace();
Utility.printExecption(LOG, e);
}
return out;
String msgTableName = MessageShardingUtil.getMessageTable(MessageShardingUtil.getMsgIdFromTimestamp(System.currentTimeMillis()));
clearOneTable(msgTableName);
}
private static void clearOneTable(String tableName) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
long mid = getMaxMidNeedClean();
try {
connection = DBUtil.getConnection();
String sql = "delete from " + tableName + " where _mid <= " + mid;
statement = connection.prepareStatement(sql);
int count = statement.executeUpdate();
LOG.info("Delete history message {} rows", count);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
//从数据源中获取数据库的连接
public static Connection getConnection() throws SQLException {
long threadId = Thread.currentThread().getId();
}
if (map.get(threadId) != null) {
LOG.error("error here!!!! DB connection not close correctly");
}
map.put(threadId, Thread.currentThread().getStackTrace().toString());
Connection connection = transactionConnection.get();
if (connection != null) {
LOG.debug("Thread {} get db connection {}", threadId, connection);
return connection;
private static List<String> getCreateSql() {
List<String> out = new ArrayList<>();
try{
BufferedReader br = new BufferedReader(new FileReader("h2/create_table.sql"));//构造一个BufferedReader类来读取文件
String s = null;
StringBuilder result = new StringBuilder();
while((s = br.readLine())!=null) {
result.append(s);
if (s.contains(";")) {
out.add(result.toString());
result = new StringBuilder();
}
}
br.close();
}catch(Exception e){
e.printStackTrace();
Utility.printExecption(LOG, e);
}
return out;
}
//从数据源中获取数据库的连接
public static Connection getConnection() throws SQLException {
long threadId = Thread.currentThread().getId();
connection = comboPooledDataSource.getConnection();
if (map.get(threadId) != null) {
LOG.error("error here!!!! DB connection not close correctly");
}
map.put(threadId, Thread.currentThread().getStackTrace().toString());
Connection connection = transactionConnection.get();
if (connection != null) {
LOG.debug("Thread {} get db connection {}", threadId, connection);
return connection;
}
public static void beginTransaction() {
try {
Connection connection = getConnection();
connection.setAutoCommit(false);
transactionConnection.set(connection);
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
connection = comboPooledDataSource.getConnection();
LOG.debug("Thread {} get db connection {}", threadId, connection);
return connection;
}
public static void beginTransaction() {
try {
Connection connection = getConnection();
connection.setAutoCommit(false);
transactionConnection.set(connection);
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
public static void commit() {
try {
@@ -180,57 +292,57 @@ public class DBUtil {
}
}
//释放资源,将数据库连接还给数据库连接池
public static void closeDB(Connection conn,PreparedStatement ps,ResultSet rs) {
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
try {
if (rs!=null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
if (ps!=null) {
ps.close();
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
if (conn!=null && transactionConnection.get() != conn) {
conn.close();
map.remove(Thread.currentThread().getId());
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
//释放资源,将数据库连接还给数据库连接池
public static void closeDB(Connection conn,PreparedStatement ps,ResultSet rs) {
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
try {
if (rs!=null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
//释放资源,将数据库连接还给数据库连接池
public static void closeDB(Connection conn, PreparedStatement ps) {
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
try {
if (ps!=null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
if (conn!=null && transactionConnection.get() != conn) {
conn.close();
map.remove(Thread.currentThread().getId());
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
try {
if (ps!=null) {
ps.close();
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
if (conn!=null && transactionConnection.get() != conn) {
conn.close();
map.remove(Thread.currentThread().getId());
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
//释放资源,将数据库连接还给数据库连接池
public static void closeDB(Connection conn, PreparedStatement ps) {
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
try {
if (ps!=null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
try {
if (conn!=null && transactionConnection.get() != conn) {
conn.close();
map.remove(Thread.currentThread().getId());
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
}
}
@@ -32,7 +32,9 @@ public class HttpUtils {
static private OkHttpClient client = new OkHttpClient();
public static void httpJsonPost(final String url, final String jsonStr){
LOG.info("POST to {} with data {}", url, jsonStr);
//消息推送内容为 {"sender":"uCGUxUaa","senderName":"杨","convType":0,"target":"usq7v7UU","targetName":"鞋子","userId":"usq7v7UU","line":0,"cntType":400,"serverTime":1610590766485,"pushMessageType":1,"pushType":2,"pushContent":"","pushData":"","unReceivedMsg":1,"mentionedType":0,"packageName":"cn.wildfirechat.chat","deviceToken":"AFoieP9P6u6CccIkRK23gRwUJWKqSkdiqnb-6gC1kL7Wv-9XNoEYBPU7VsINU_q8_WTKfafe35qWu7ya7Z-NmgOTX9XVW3A3zd6ilh--quj6ccINXRvVnh8QmI9QQ","isHiddenDetail":false,"language":"zh"}
//推送信息只打印前100个字符,防止敏感信息打印到日志中去。
LOG.info("POST to {} with data {}...", url, jsonStr.substring(0, Math.min(jsonStr.length(), 100)));
if (StringUtil.isNullOrEmpty(url)) {
LOG.error("http post failure with empty url");
return;
@@ -12,9 +12,12 @@ public interface IMTopic {
String SendMessageTopic = "MS";
String MultiCastMessageTopic = "MMC";
String RecallMessageTopic = "MR";
String RecallMultiCastMessageTopic = "MRMC";
String PullMessageTopic = "MP";
String NotifyMessageTopic = "MN";
String NotifyRecallMessageTopic = "RMN";
String NotifyOffline = "ROFL";
String BroadcastMessageTopic = "MBC";
String GetUserSettingTopic = "UG";
@@ -28,6 +31,7 @@ public interface IMTopic {
String DismissGroupTopic = "GD";
String ModifyGroupInfoTopic = "GMI";
String ModifyGroupAliasTopic = "GMA";
String ModifyGroupMemberAliasTopic = "GMMA";
String GetGroupInfoTopic = "GPGI";
String GetGroupMemberTopic = "GPGM";
String TransferGroupTopic = "GTG";
@@ -10,6 +10,7 @@ package win.liyufan.im;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
public class MessageShardingUtil {
private static SpinLock mLock = new SpinLock();
@@ -36,9 +37,8 @@ public class MessageShardingUtil {
*/
public static long generateId() throws Exception {
mLock.lock();
rotateId = (rotateId + 1)&rotateIdMask;
mLock.unLock();
rotateId = (rotateId + 1)&rotateIdMask;
long id = System.currentTimeMillis() - T201801010000;
if (id > timeId) {
@@ -75,6 +75,10 @@ public class MessageShardingUtil {
id <<= rotateIdWidth;
id += rotateId;
mLock.unLock();
return id;
}
@@ -84,7 +88,7 @@ public class MessageShardingUtil {
}
Calendar calendar = Calendar.getInstance();
if (mid != Long.MAX_VALUE) {
if (mid != Long.MAX_VALUE && mid != 0) {
mid >>= (nodeIdWidth + rotateIdWidth);
Date date = new Date(mid + T201801010000);
calendar.setTime(date);
@@ -97,8 +101,32 @@ public class MessageShardingUtil {
year %= 3;
return "t_messages_" + (year * 12 + month);
}
static Calendar getCalendarFromMessageId(long mid) {
Calendar calendar = Calendar.getInstance();
if (mid != Long.MAX_VALUE && mid != 0) {
mid >>= (nodeIdWidth + rotateIdWidth);
Date date = new Date(mid + T201801010000);
calendar.setTime(date);
} else {
Date date = new Date(System.currentTimeMillis());
calendar.setTime(date);
}
return calendar;
}
public static long getMsgIdFromTimestamp(long timestamp) {
long id = timestamp - T201801010000;
id <<= rotateIdWidth;
id <<= nodeIdWidth;
return id;
}
public static String getPreviousMessageTable(long mid) {
return getMessageTable(mid, -1);
}
public static String getMessageTable(long mid, int offset) {
if (DBUtil.IsEmbedDB) {
return null;
}
@@ -110,11 +138,40 @@ public class MessageShardingUtil {
int month = calendar.get(Calendar.MONTH);
int year = calendar.get(Calendar.YEAR);
year %= 3;
month = month - 1;
if (month == -1) {
month = 11;
month = month + offset;
while (month < 0) {
month += 12;
year = (year + 3 - 1)%3;
}
while (month >= 12) {
month -= 12;
year = (year + 1)%3;
}
return "t_messages_" + (year * 12 + month);
}
public static void main(String[] args) throws Exception {
ConcurrentHashMap<Long, Integer> messageIds = new ConcurrentHashMap<>();
int threadCount = 1000;
int loop = 1000000;
for (int i = 0; i < threadCount; i++) {
new Thread(()->{
for (int j = 0; j < loop; j++) {
try {
long mid = generateId();
if(messageIds.put(mid, j) != null) {
System.out.println("Duplicated message id !!!!!!" + mid);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
Thread.sleep(1000 * 60 * 10);
}
}
@@ -3,15 +3,11 @@ package win.liyufan.im;
public interface UserSettingScope {
int kUserSettingConversationSilent = 1;
int kUserSettingGlobalSilent = 2;
int kUserSettingConversationTop = 3;
int kUserSettingHiddenNotificationDetail = 4;
int kUserSettinGroupHideNickname = 5;
int kUserSettingFavouriteGroup = 6;
int kUserSettingConversationSync = 7;
int kUserSettingMyChannels = 8;
int kUserSettingListenedChannels = 9;
int kUserSettingPCOnline = 10;
int kUserSettingCustomBegin = 1000;
int kUserSettingMuteWhenPCOnline = 15;
int kUserSettingNoDisturbing = 17;
}
@@ -8,12 +8,35 @@
package win.liyufan.im;
import cn.wildfirechat.common.IMExceptionEvent;
import com.google.gson.Gson;
import com.hazelcast.util.StringUtil;
import io.moquette.server.Server;
import org.slf4j.Logger;
import java.net.*;
import java.util.Enumeration;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
public class Utility {
private static Map<String, IMExceptionEvent> exceptionEventHashMap = new ConcurrentHashMap<>();
static AtomicLong SendExceptionExpireTime = new AtomicLong(0);
static int SendExceptionDuration = 180000;
static long lastSendTime = System.currentTimeMillis();
static {
new Thread(()->{
while (true) {
try {
Thread.sleep(60 * 1000);
sendExceptionEvent();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public static InetAddress getLocalAddress(){
try {
Enumeration<NetworkInterface> b = NetworkInterface.getNetworkInterfaces();
@@ -29,6 +52,10 @@ public class Utility {
}
public static void printExecption(Logger LOG, Exception e) {
printExecption(LOG, e, 0);
}
public static void printExecption(Logger LOG, Exception e, int eventType) {
String message = "";
for(StackTraceElement stackTraceElement : e.getStackTrace()) {
@@ -36,6 +63,58 @@ public class Utility {
}
LOG.error("Exception: {}", e.getMessage());
LOG.error(message);
if(eventType > 0) {
String key = eventType+(e.getMessage() != null ? e.getMessage().split("\n")[0] : "null");
IMExceptionEvent event = exceptionEventHashMap.get(key);
if(event == null) {
event = new IMExceptionEvent();
event.event_type = eventType;
event.msg = e.getMessage();
event.call_stack = message;
event.count = 0;
exceptionEventHashMap.put(key, event);
}
event.count++;
sendExceptionEvent();
}
}
private static String gMonitorEventAddress;
public static void setMonitorEventAddress(String gMonitorEventAddress) {
Utility.gMonitorEventAddress = gMonitorEventAddress;
}
private static void sendExceptionEvent() {
if(StringUtil.isNullOrEmpty(gMonitorEventAddress)) {
return;
}
long now = System.currentTimeMillis();
long t = SendExceptionExpireTime.getAndUpdate((long l) -> now - l >= SendExceptionDuration ? now : l);
if(now - t >= SendExceptionDuration) {
for (Map.Entry<String, IMExceptionEvent> entry : exceptionEventHashMap.entrySet()) {
if(entry.getValue().count > 0) {
String jsonStr = new Gson().toJson(entry.getValue());
Server.getServer().getCallbackScheduler().execute(() -> HttpUtils.httpJsonPost(gMonitorEventAddress, jsonStr));
entry.getValue().count = 0;
lastSendTime = now;
}
}
if(now - lastSendTime > 24 * 3600 * 1000) {
lastSendTime = now;
IMExceptionEvent event = new IMExceptionEvent();
event.event_type = 0;
event.msg = "监控心跳通知";
event.call_stack = "别担心!这个是心跳消息,已经有24小时没有出现异常消息了!";
event.count = IMExceptionEvent.EventType.HEART_BEAT;
String jsonStr = new Gson().toJson(event);
Server.getServer().getCallbackScheduler().execute(() -> HttpUtils.httpJsonPost(gMonitorEventAddress, jsonStr));
}
}
}
public static String getMacAddress() throws UnknownHostException,
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.44</version>
<version>0.53</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -28,7 +28,9 @@ public interface APIPath {
String User_Get_Blocked_List = "/admin/user/get_blocked_list";
String User_Check_Block_Status = "/admin/user/check_block_status";
String User_Get_Online_Status = "/admin/user/onlinestatus";
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 Friend_Update_Status = "/admin/friend/status";
String Friend_Get_List = "/admin/friend/list";
@@ -36,12 +38,17 @@ public interface APIPath {
String Blacklist_Get_List = "/admin/blacklist/list";
String Friend_Get_Alias = "/admin/friend/get_alias";
String Friend_Set_Alias = "/admin/friend/set_alias";
String Friend_Send_Request = "/admin/friend/send_request";
String Friend_Get_Requests = "/admin/friend/get_requests";
String Relation_Get = "/admin/relation/get";
String Msg_Send = "/admin/message/send";
String Msg_Recall = "/admin/message/recall";
String Msg_Delete = "/admin/message/delete";
String Msg_Broadcast = "/admin/message/broadcast";
String Msg_Multicast = "/admin/message/multicast";
String Msg_RecallBroadCast = "/admin/message/recall_broadcast";
String Msg_RecallMultiCast = "/admin/message/recall_multicast";
String Create_Group = "/admin/group/create";
String Group_Dismiss = "/admin/group/del";
@@ -56,7 +63,7 @@ public interface APIPath {
String Group_Mute_Member = "/admin/group/manager/mute";
String Group_Allow_Member = "/admin/group/manager/allow";
String Get_User_Groups = "/admin/group/of_user";
String Group_Set_Member_Alias = "/admin/group/member/set_alias";
String Create_Channel = "/admin/channel/create";
String Get_System_Setting = "/admin/system/get_setting";
@@ -71,4 +78,25 @@ public interface APIPath {
String Robot_User_Info = "/robot/user_info";
String Robot_Message_Send = "/robot/message/send";
String Robot_Set_Callback = "/robot/set_callback";
String Robot_Get_Callback = "/robot/get_callback";
String Robot_Delete_Callback = "/robot/delete_callback";
String Robot_Update_Profile = "/robot/update_profile";
String Robot_Verify_Application_User = "/robot/user/verify";
String Robot_Group_Member_Add = "/robot/group/member/add";
String Robot_Group_Allow_Member = "/robot/group/manager/allow";
String Robot_Create_Group = "/robot/group/create";
String Robot_Group_Dismiss = "/robot/group/del";
String Robot_Group_Get_Info = "/robot/group/get_info";
String Robot_Group_Member_List = "/robot/group/member/list";
String Robot_Group_Member_Kickoff = "/robot/group/member/del";
String Robot_Group_Modify_Info = "/robot/group/modify";
String Robot_Group_Set_Member_Alias = "/robot/group/member/set_alias";
String Robot_Group_Mute_Member = "/robot/group/manager/mute";
String Robot_Group_Member_Quit = "/robot/group/member/quit";
String Robot_Group_Transfer = "/robot/group/transfer";
String Robot_Group_Set_Manager = "/robot/group/manager/set";
}
@@ -0,0 +1,21 @@
package cn.wildfirechat.common;
public class IMExceptionEvent {
public interface EventType {
int RDBS_Exception = 1;
int MONGO_Exception = 2;
int RPC_Exception = 3;
int PUSH_SERVER_Exception = 4;
int ADMIN_API_Exception = 5;
int CHANNEL_API_Exception = 6;
int ROBOT_API_Exception = 7;
int SHORT_LINK_Exception = 8;
int EVENT_CALLBACK_Exception = 9;
int HEART_BEAT = 100;
}
public int event_type;
public String msg;
public String call_stack;
public int count;
}
@@ -0,0 +1,7 @@
package cn.wildfirechat.pojos;
public class ChannelUpdateEvent {
public String operatorId;
public String channelId;
public int type;
}
@@ -0,0 +1,10 @@
package cn.wildfirechat.pojos;
import java.util.List;
public class ChatroomMemberUpdateEvent {
public String operatorId;
public String chatroomId;
public List<String> memberIds;
public int type;
}
@@ -0,0 +1,6 @@
package cn.wildfirechat.pojos;
public class ChatroomUpdateEvent {
public String chatroomId;
public int type;
}
@@ -0,0 +1,11 @@
package cn.wildfirechat.pojos;
import java.util.List;
public class GroupMemberUpdateEvent {
public String operatorId;
public String groupId;
public List<String> memberIds;
public int type;
public String value;
}
@@ -105,10 +105,18 @@ public class GroupNotificationBinaryContent {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_KICKOF_GROUP_MEMBER);
}
public WFCMessage.MessageContent getKickokfMemberVisibleGroupNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_KICKOF_GROUP_MEMBER_VISIBLE);
}
public WFCMessage.MessageContent getQuitGroupNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_QUIT_GROUP);
}
public WFCMessage.MessageContent getQuitVisibleGroupNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_QUIT_GROUP_VISIBLE);
}
public WFCMessage.MessageContent getTransferGroupNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_TRANSFER_GROUP_OWNER);
}
@@ -0,0 +1,7 @@
package cn.wildfirechat.pojos;
public class GroupUpdateEvent {
public String operatorId;
public String groupId;
public int type;
}
@@ -0,0 +1,50 @@
/*
* 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 InputAddFriendRequest {
private String userId;
private String friendUid;
private String reason;
private boolean force;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getFriendUid() {
return friendUid;
}
public void setFriendUid(String friendUid) {
this.friendUid = friendUid;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public boolean isForce() {
return force;
}
public void setForce(boolean force) {
this.force = force;
}
}
@@ -0,0 +1,67 @@
/*
* 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;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
import java.util.List;
public class InputSetGroupMemberAlias extends InputGroupBase {
private String group_id;
private String memberId;
private String alias;
public String getGroup_id() {
return group_id;
}
public void setGroup_id(String group_id) {
this.group_id = group_id;
}
public boolean isValide() {
return true;
}
public WFCMessage.ModifyGroupMemberAlias toProtoGroupRequest() {
WFCMessage.ModifyGroupMemberAlias.Builder modifyAliasBuilder = WFCMessage.ModifyGroupMemberAlias.newBuilder();
modifyAliasBuilder.setGroupId(group_id);
modifyAliasBuilder.setAlias(StringUtil.isNullOrEmpty(alias)?"":alias);
modifyAliasBuilder.setMemberId(memberId);
if (to_lines != null) {
for (Integer line : to_lines) {
modifyAliasBuilder.addToLine(line);
}
}
if (notify_message != null) {
modifyAliasBuilder.setNotifyContent(notify_message.toProtoMessageContent());
}
return modifyAliasBuilder.build();
}
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
}
@@ -9,7 +9,7 @@
package cn.wildfirechat.pojos;
public class InputFriendRequest {
public class InputUpdateFriendStatusRequest {
private String userId;
private String friendUid;
private int status;
@@ -0,0 +1,38 @@
/*
* 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 IntStringPairPojo {
private int intValue;
private String strValue;
public IntStringPairPojo() {
}
public IntStringPairPojo(int intValue, String strValue) {
this.intValue = intValue;
this.strValue = strValue;
}
public int getIntValue() {
return intValue;
}
public void setIntValue(int intValue) {
this.intValue = intValue;
}
public String getStrValue() {
return strValue;
}
public void setStrValue(String strValue) {
this.strValue = strValue;
}
}
@@ -6,7 +6,7 @@
* file that was distributed with this source code.
*/
package win.liyufan.im;
package cn.wildfirechat.pojos;
public interface MyInfoType {
int Modify_DisplayName = 0;
@@ -0,0 +1,17 @@
/*
* 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;
import java.util.List;
public class RecallMultiCastMessageData {
public String operator;
public long messageUid;
public List<String> receivers;
}
@@ -0,0 +1,10 @@
package cn.wildfirechat.pojos;
public class RelationPojo {
public String userId;
public String targetId;
public boolean isFriend;
public boolean isBlacked;
public String alias;
public String extra;
}

Some files were not shown because too many files have changed in this diff Show More