Compare commits

...
89 Commits
Author SHA1 Message Date
heavyrain2012 f6e8cd4ca8 update version to 0.55 2021-03-01 18:51:57 +08:00
heavyrain2012 da74b9fa94 添加更新接口 2021-02-24 15:46:46 +08:00
imhao183 281fe4c955 update version 2021-02-23 18:06:50 +08:00
imhao183 adfa3d3031 添加flyway修复说明 2021-02-23 18:05:31 +08:00
imhao183 6c34a9e512 remove default sensitive word 2021-02-23 18:01:28 +08:00
heavyrain.lee 0fd56ba61d Update README.md 2021-02-18 17:06:12 +08:00
imhao183 01342174af 去掉对客户端版本的限制,以便支持更新版本的客户端sdk 2021-02-16 11:27:49 +08:00
heavyrain2012 4742b135a5 添加消息转发类型过滤参数 2021-02-14 15:00:50 +08:00
heavyrain2012 6466218836 添加对接第三方敏感词处理方法 2021-02-14 12:30:40 +08:00
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
118 changed files with 5222 additions and 4855 deletions
+4 -3
View File
@@ -7,7 +7,7 @@
| [android-chat](https://github.com/wildfirechat/android-chat) | 野火IM Android SDK源码和App源码 |可以很方便地进行二次开发,或集成到现有应用当中 | | [android-chat](https://github.com/wildfirechat/android-chat) | 野火IM Android SDK源码和App源码 |可以很方便地进行二次开发,或集成到现有应用当中 |
| [ios-chat](https://github.com/wildfirechat/ios-chat) | 野火IM iOS SDK源码和App源码 |可以很方便地进行二次开发,或集成到现有应用当中 | | [ios-chat](https://github.com/wildfirechat/ios-chat) | 野火IM iOS SDK源码和App源码 |可以很方便地进行二次开发,或集成到现有应用当中 |
| [pc-chat](https://github.com/wildfirechat/pc-chat) | 基于[Electron](https://electronjs.org/)开发的PC平台应用 | | | [pc-chat](https://github.com/wildfirechat/pc-chat) | 基于[Electron](https://electronjs.org/)开发的PC平台应用 | |
| [web-chat](https://github.com/wildfirechat/web-chat) | Web平台的Demo, [体验地址](http://web.wildfirechat.cn) | | | [web-chat](https://github.com/wildfirechat/web-chat) | Web平台的Demo, [体验地址](http://web.wildfirechat.net) | |
| [wx-chat](https://github.com/wildfirechat/wx-chat) | 微信小程序平台的Demo | | | [wx-chat](https://github.com/wildfirechat/wx-chat) | 微信小程序平台的Demo | |
| [server](https://github.com/wildfirechat/server) | IM server | | | [server](https://github.com/wildfirechat/server) | IM server | |
| [app server](https://github.com/wildfirechat/app_server) | 应用服务端 | | | [app server](https://github.com/wildfirechat/app_server) | 应用服务端 | |
@@ -16,7 +16,7 @@
| [docs](https://github.com/wildfirechat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明 | | | | | [docs](https://github.com/wildfirechat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明 | | | |
# server # server
本工程为野火IM 社区版IM服务软件。野火IM作为一个通用的即时通讯解决方案,可以集成到各种应用中。请阅读[docs](http://docs.wildfirechat.cn)或下载服务器[发布版本](https://github.com/wildfirechat/server/releases) 本工程为野火IM 社区版IM服务软件。野火IM作为一个通用的即时通讯解决方案,可以集成到各种应用中。请阅读[docs](http://docs.wildfirechat.net)或下载服务器[发布版本](https://github.com/wildfirechat/server/releases)
开发一套IM系统真的很艰辛,请路过的朋友们给点个star,支持我们坚持下去🙏🙏🙏🙏🙏 开发一套IM系统真的很艰辛,请路过的朋友们给点个star,支持我们坚持下去🙏🙏🙏🙏🙏
@@ -72,7 +72,8 @@
## 升级说明 ## 升级说明
1. 从0.42 版本增加了群成员数限制,默认为2000。如果您从之前的版本升级到这个版本或以后,需要注意到群成员数的限制。升级之后超出限制的群不受影响,但不能继续加人,如果您想修改默认值,可以在升级版本之后,修改t_setting表,把默认的大小改为您期望的人数。另外修改t_group表,把已经存在的群组max_member_count改成您期望的,然后重启。 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版本之外的版本不会出现此问题。
3. 从0.54之前版本升级到0.54及以后版本时,会提示flyway migrate错误。因为0.54版本删除了sql脚本中默认敏感词的内容,flyway checksum失败。请执行```update flyway_schema_history set checksum = 0 where script = 'V17__add_default_sensitive_word.sql';```来修复。
## 特别感谢 ## 特别感谢
1. [moquette](https://github.com/moquette-io/moquette) 本项目是基于此项目二次开发而来,处理MQTT相关业务。 1. [moquette](https://github.com/moquette-io/moquette) 本项目是基于此项目二次开发而来,处理MQTT相关业务。
+80 -27
View File
@@ -20,9 +20,6 @@ port 1883
##客户端短链接端口 ##客户端短链接端口
http_port 80 http_port 80
##WEB客户端长链接端口
websocket_port 8083
#管理端口 #管理端口
http.admin.port 18080 http.admin.port 18080
@@ -38,6 +35,11 @@ local_port 80
##是否使用内置DB。0使用mysql;1使用h2db;2使用mysql+mongodb。社区版只支持0和1,专业版支持2 ##是否使用内置DB。0使用mysql;1使用h2db;2使用mysql+mongodb。社区版只支持0和1,专业版支持2
embed.db 1 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 http.admin.secret_key 123456
@@ -46,9 +48,6 @@ http.admin.secret_key 123456
##这个地方上线前要改为false ##这个地方上线前要改为false
http.admin.no_check_time true 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的私钥,只在服务器使用,客户端不用。正式使用时为了安全一定要修改这个值,切记切记 ##用来生产im token的私钥,只在服务器使用,客户端不用。正式使用时为了安全一定要修改这个值,切记切记
token.key testim token.key testim
@@ -78,6 +77,10 @@ message.disable_remote_search false
##允许客户端撤回消息时限,单位是秒。群组管理员或群主撤回群成员消息、server api不受此限制,可以撤回任意时限内的消息 ##允许客户端撤回消息时限,单位是秒。群组管理员或群主撤回群成员消息、server api不受此限制,可以撤回任意时限内的消息
message.recall_time_limit 120 message.recall_time_limit 120
## 禁止客户端发送消息类型,消息类型以逗号分开,下面3个值为示例,可以删除。
## 一般用于重要类型消息,比如交易、充值等,禁止客户端发送,仅限于服务器发送,提高安全性。
message.forbidden_client_send_types 3999,4000,4001
##禁止搜索用户 ##禁止搜索用户
friend.disable_search false friend.disable_search false
@@ -108,6 +111,18 @@ chatroom.participant_idle_time 900000
## 用户向聊天室发送消息,自动加入聊天室 ## 用户向聊天室发送消息,自动加入聊天室
chatroom.rejoin_when_active true 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 # hazelcase configuration
#********************************************************************* #*********************************************************************
@@ -166,40 +181,78 @@ server.multi_platform_notification false
#********************************************************************* #*********************************************************************
# Push server configuration # Push server configuration
#********************************************************************* #*********************************************************************
##推送服务项目地址:https://github.com/wildfirechat/push_server。
##安卓推送服务器地址 ##安卓推送服务器地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
push.android.server.address http://localhost:8085/android/push push.android.server.address http://localhost:8085/android/push
##苹果推送服务器地址 ##苹果推送服务器地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
push.ios.server.address http://localhost:8085/ios/push push.ios.server.address http://localhost:8085/ios/push
#********************************************************************* #*********************************************************************
# User online status event callback # 监控配置
#********************************************************************* #*********************************************************************
##用户在线状态事件回调地址 #monitor.exception_event_address http://localhost:8888/im_exception_event/
#user.online_status_callback http://localhost:8888/user/online_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 #user.online_status_callback http://localhost:8888/im_event/user/online
mongodb.client_uri mongodb://wfc:123456@localhost:27017/wfchat
mongodb.database wfchat ##用户信息变动事件回调地址
#仅在第一次启动时会设置消息数据的过期时间,如果之后再修改将不生效。 ##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#如果需要修改过期时间,请修改t_messages_x和t_user_message_x的索引过期时间,修改方法请行百度 #relation.relation_update_callback http://localhost:8888/im_event/user/relation
mongodb.data_expire_days 1096
##用户信息变动事件回调地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#user.user_info_update_callback http://localhost:8888/im_event/user/info
##消息转发地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#message.forward.url http://localhost:8888/im_event/message
##需要转发的消息类型,当有多个时以英文逗号分割。如果转发所有消息,请注释掉配置或者设置为空
#message.forward.types 1,2,3
##设备信息转发地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#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 # Sensitive configuration
#********************************************************************* #*********************************************************************
##文本敏感词过滤处理方法,0 发送失败;1 发送成功但消息被服务器直接丢弃;2 命中的敏感词被替换成***;3 记录并继续发送 ## 内置文本敏感词过滤处理方法,0 发送失败;1 发送成功但消息被服务器直接丢弃;2 命中的敏感词被替换成***;3 记录并继续发送
sensitive.filter.type 0 sensitive.filter.type 0
#********************************************************************* ## 如果内置敏感词库无法满足您的需求,可以自己开发部署敏感词审核服务。配置如下地址和消息类型,IM服务会把指定消息类型的消息回调到指定地址
# Message forward configuration ## 审核服务返回状态码200表示继续发送,如果需要替换内容,返回状态码200并且内容为替换后的内容。返回403表示不允许发送。其它错误继续发送。
#********************************************************************* ## 独立审核服务地址,IM服务会post SendMessageData。如果需要修改消息内容,返回 MessagePayload。请参考应用服务中 "/message/censor" Mapping.
##消息转发地址 #sensitive.remote_server_url http://192.168.3.202:8888/message/censor
#message.forward.url http://localhost:8087/message/forward ## 需要进行敏感词审核的消息类型,当有多个时以英文逗号分割
#sensitive.remote_sensitive_message_type 1,2,3
##设备信息转发地址 ## 如果远程审核服务返回403,返回给发送端发送失败还是成功?实际上这个值影响发送响应是否等待审核结果,当为false时,消息发送给审核服务就立即返回
#things_message.forward.url http://localhost:8087/device/forward ## 成功给客户端。当为true时,消息发送给审核服务,等待审核结果,如果结果为继续发送就返回给客户端为成功,结果为禁止发送就返回失败给客户端。
## 客户端操作的超时一般为10s左右,且考虑到复杂的网络情况,建议处理时间不要超过3s。建议这个值为false。
#sensitive.remote_fail_when_matched false
+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`)
);
+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`);
File diff suppressed because it is too large Load Diff
@@ -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;
@@ -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> <relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId> <groupId>cn.wildfirechat</groupId>
<version>0.46</version> <version>0.55</version>
</parent> </parent>
<artifactId>moquette-broker</artifactId> <artifactId>moquette-broker</artifactId>
@@ -132,7 +132,7 @@
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.8.2</version> <version>4.13.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
@@ -198,13 +198,6 @@
<version>2.5</version> <version>2.5</version>
</dependency> </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 --> <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
@@ -15,6 +15,7 @@ public class PushMessage {
public int convType; public int convType;
public String target; public String target;
public String targetName; public String targetName;
public String userId;
public int line; public int line;
public int cntType; public int cntType;
public long serverTime; public long serverTime;
@@ -42,7 +43,16 @@ public class PushMessage {
this.cntType = messageContentType; this.cntType = messageContentType;
this.serverTime = serverTime; this.serverTime = serverTime;
this.unReceivedMsg = unReceivedMsg; 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.mentionedType = mentionedType;
this.isHiddenDetail = isHiddenDetail; this.isHiddenDetail = isHiddenDetail;
this.language = language; this.language = language;
@@ -8,12 +8,11 @@
package cn.wildfirechat.push; package cn.wildfirechat.push;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson; import com.google.gson.Gson;
import io.moquette.persistence.MemorySessionStore; import io.moquette.persistence.MemorySessionStore;
import io.moquette.server.config.IConfig; import io.moquette.server.config.IConfig;
import io.moquette.spi.ClientSession;
import io.moquette.spi.ISessionsStore; import io.moquette.spi.ISessionsStore;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -35,6 +34,7 @@ public class PushServer {
int PUSH_MESSAGE_TYPE_VOIP_INVITE = 1; int PUSH_MESSAGE_TYPE_VOIP_INVITE = 1;
int PUSH_MESSAGE_TYPE_VOIP_BYE = 2; int PUSH_MESSAGE_TYPE_VOIP_BYE = 2;
int PUSH_MESSAGE_TYPE_FRIEND_REQUEST = 3; int PUSH_MESSAGE_TYPE_FRIEND_REQUEST = 3;
int PUSH_MESSAGE_TYPE_VOIP_ANSWER = 4;
} }
private static PushServer INSTANCE = new PushServer(); private static PushServer INSTANCE = new PushServer();
@@ -64,7 +64,7 @@ public class PushServer {
pushMessageInternel(pushMessage, deviceId, pushContent); pushMessageInternel(pushMessage, deviceId, pushContent);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); 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.pushContent = pushContent;
pushMessage.deviceToken = session.getDeviceToken(); pushMessage.deviceToken = session.getDeviceToken();
pushMessage.unReceivedMsg = badge; pushMessage.unReceivedMsg = badge;
pushMessage.userId = session.getUsername();
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_Android) { if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_Android) {
String url = androidPushServerUrl; String url = androidPushServerUrl;
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS) { if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS) {
@@ -80,9 +80,12 @@ public class LoFileServer {
channel = b.bind(port).sync().channel(); channel = b.bind(port).sync().channel();
Logger.info("***** Welcome To LoServer on port [{}], startting spend {}ms *****", port, DateUtil.spendMs(start)); 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() { public void shutdown() {
if (this.channel != null) { if (this.channel != null) {
@@ -62,6 +62,7 @@ public class LoServer {
registerAllAction(); registerAllAction();
int bindingPort = port;
try { try {
final ServerBootstrap b = new ServerBootstrap(); final ServerBootstrap b = new ServerBootstrap();
final ServerBootstrap adminB = new ServerBootstrap(); final ServerBootstrap adminB = new ServerBootstrap();
@@ -87,6 +88,7 @@ public class LoServer {
channel = b.bind(port).sync().channel(); channel = b.bind(port).sync().channel();
bindingPort = adminPort;
adminB.group(bossGroup, workerGroup) adminB.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) .channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 10240) // 服务端可连接队列大小 .option(ChannelOption.SO_BACKLOG, 10240) // 服务端可连接队列大小
@@ -108,10 +110,14 @@ public class LoServer {
adminChannel = adminB.bind(adminPort).sync().channel(); adminChannel = adminB.bind(adminPort).sync().channel();
Logger.info("***** Welcome To LoServer on port [{},{}], startting spend {}ms *****", port, adminPort, DateUtil.spendMs(start)); 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() { public void shutdown() {
if (this.channel!= null) { if (this.channel!= null) {
this.channel.close(); this.channel.close();
@@ -110,7 +110,7 @@ public class FileAction extends Action {
// 路径安全检查 // 路径安全检查
String path = httpPath.substring(0, httpPath.lastIndexOf("/")); 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; return null;
} }
@@ -9,6 +9,7 @@
package com.xiaoleilu.loServer.action.admin; package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath; import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult; import com.xiaoleilu.loServer.RestResult;
@@ -63,7 +64,7 @@ public class CreateRobotAction extends AdminAction {
messagesStore.addUserInfo(newUser, inputCreateRobot.getPassword()); messagesStore.addUserInfo(newUser, inputCreateRobot.getPassword());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
response.setStatus(HttpResponseStatus.OK); response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage()); RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
response.setContent(new Gson().toJson(result)); response.setContent(new Gson().toJson(result));
@@ -9,6 +9,7 @@
package com.xiaoleilu.loServer.action.admin; package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath; import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson; import com.google.gson.Gson;
@@ -25,7 +26,6 @@ import io.netty.util.internal.StringUtil;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import win.liyufan.im.DBUtil;
import win.liyufan.im.UUIDGenerator; import win.liyufan.im.UUIDGenerator;
import win.liyufan.im.Utility; import win.liyufan.im.Utility;
@@ -88,7 +88,7 @@ public class CreateUserAction extends AdminAction {
messagesStore.addUserInfo(newUserBuilder.build(), inputCreateUser.getPassword()); messagesStore.addUserInfo(newUserBuilder.build(), inputCreateUser.getPassword());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
response.setStatus(HttpResponseStatus.OK); response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage()); RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
response.setContent(new Gson().toJson(result)); response.setContent(new Gson().toJson(result));
@@ -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;
}
}
@@ -0,0 +1,65 @@
/*
* 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.common.IMExceptionEvent;
import cn.wildfirechat.pojos.InputOutputUserInfo;
import cn.wildfirechat.pojos.InputUpdateUserInfo;
import cn.wildfirechat.pojos.OutputCreateUser;
import cn.wildfirechat.proto.ProtoConstants;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.UUIDGenerator;
import win.liyufan.im.Utility;
@Route(APIPath.Update_User)
@HttpMethod("POST")
public class UpdateUserAction extends AdminAction {
private static final Logger LOG = LoggerFactory.getLogger(UpdateUserAction.class);
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputUpdateUserInfo inputCreateUser = getRequestBody(request.getNettyRequest(), InputUpdateUserInfo.class);
if (inputCreateUser != null
&& inputCreateUser.userInfo != null
&& !StringUtil.isNullOrEmpty(inputCreateUser.userInfo.getUserId())
&& inputCreateUser.flag > 0) {
ErrorCode errorCode = messagesStore.updateUserInfo(inputCreateUser.userInfo, inputCreateUser.flag);
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(errorCode);
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;
}
}
@@ -8,11 +8,11 @@
package com.xiaoleilu.loServer.action.channel; package com.xiaoleilu.loServer.action.channel;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult; import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.admin.AdminAction;
import com.xiaoleilu.loServer.handler.Request; import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response; import com.xiaoleilu.loServer.handler.Response;
import io.moquette.spi.impl.Utils; import io.moquette.spi.impl.Utils;
@@ -63,7 +63,7 @@ abstract public class ChannelAction extends Action {
ts = Long.parseLong(timestamp); ts = Long.parseLong(timestamp);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, IMExceptionEvent.EventType.CHANNEL_API_Exception);
return ErrorCode.INVALID_PARAMETER; return ErrorCode.INVALID_PARAMETER;
} }
@@ -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; package com.xiaoleilu.loServer.action.robot;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult; import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.handler.Request; import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response; import com.xiaoleilu.loServer.handler.Response;
import io.moquette.imhandler.IMHandler;
import io.moquette.spi.impl.Utils; import io.moquette.spi.impl.Utils;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequest;
@@ -67,7 +67,7 @@ abstract public class RobotAction extends Action {
ts = Long.parseLong(timestamp); ts = Long.parseLong(timestamp);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ROBOT_API_Exception);
return ErrorCode.INVALID_PARAMETER; return ErrorCode.INVALID_PARAMETER;
} }
@@ -112,7 +112,7 @@ abstract public class RobotAction extends Action {
return t; return t;
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ROBOT_API_Exception);
} }
} }
return null; 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; package com.xiaoleilu.loServer.handler;
import java.io.IOException; import cn.wildfirechat.common.IMExceptionEvent;
import com.hazelcast.core.HazelcastInstance;
import com.xiaoleilu.hutool.lang.Singleton; 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.ServerSetting;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.UnknownErrorAction; import com.xiaoleilu.loServer.action.UnknownErrorAction;
@@ -53,7 +49,7 @@ abstract public class ActionHandler extends SimpleChannelInboundHandler<FullHttp
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(Logger, e); Utility.printExecption(Logger, e, IMExceptionEvent.EventType.SHORT_LINK_Exception);
Action errorAction = ServerSetting.getErrorAction(ServerSetting.MAPPING_ERROR); Action errorAction = ServerSetting.getErrorAction(ServerSetting.MAPPING_ERROR);
request.putParam(UnknownErrorAction.ERROR_PARAM_NAME, e); request.putParam(UnknownErrorAction.ERROR_PARAM_NAME, e);
response.setContent(e.toString()); response.setContent(e.toString());
@@ -11,8 +11,6 @@ import io.netty.util.CharsetUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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.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_RANGE;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; 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 { public class HttpResponseHelper {
private static final Logger logger = LoggerFactory.getLogger(HttpResponseHelper.class); private static final Logger logger = LoggerFactory.getLogger(HttpResponseHelper.class);
private static final MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
/** /**
* sendResponse * sendResponse
@@ -149,7 +146,7 @@ public static String getContentType(String fileName) {
if (fileExtName.equals("png")) { // MimetypesFileTypeMap目前缺少png类型 if (fileExtName.equals("png")) { // MimetypesFileTypeMap目前缺少png类型
return "image/png"; return "image/png";
} else { } else {
return mimetypesFileTypeMap.getContentType(fileName); return "application/octet-stream";
} }
} }
@@ -357,8 +357,8 @@ public class Response {
final DefaultHttpResponse defaultHttpResponse = new DefaultHttpResponse(httpVersion, status); final DefaultHttpResponse defaultHttpResponse = new DefaultHttpResponse(httpVersion, status);
// headers // headers
final HttpHeaders httpHeaders = defaultHttpResponse.headers().add(headers); HttpHeaders httpHeaders = defaultHttpResponse.headers().add(headers);
httpHeaders.set(HttpHeaderNames.CONTENT_TYPE.toString(), contentType);
// Cookies // Cookies
for (Cookie cookie : cookies) { for (Cookie cookie : cookies) {
httpHeaders.add(HttpHeaderNames.SET_COOKIE.toString(), ServerCookieEncoder.LAX.encode(cookie)); 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_MOQUETTE_STORE_MAP_DB_FILENAME = "moquette_store.mapdb";
public static final String DEFAULT_PERSISTENT_PATH = System.getProperty("user.dir") + File.separator public static final String DEFAULT_PERSISTENT_PATH = System.getProperty("user.dir") + File.separator
+ DEFAULT_MOQUETTE_STORE_MAP_DB_FILENAME; + 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 WSS_PORT_PROPERTY_NAME = "secure_websocket_port";
public static final String SSL_PORT_PROPERTY_NAME = "ssl_port"; public static final String SSL_PORT_PROPERTY_NAME = "ssl_port";
public static final String JKS_PATH_PROPERTY_NAME = "jks_path"; 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_QUERY = "authenticator.db.query";
public static final String DB_AUTHENTICATOR_DIGEST = "authenticator.db.digest"; public static final String DB_AUTHENTICATOR_DIGEST = "authenticator.db.digest";
public static final int PORT = 1883; 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 DISABLED_PORT_BIND = "disabled";
public static final String HOST = "0.0.0.0"; public static final String HOST = "0.0.0.0";
public static final String NEED_CLIENT_AUTH = "need_client_auth"; 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_ANDROID_SERVER_ADDRESS = "push.android.server.address";
public static final String PUSH_IOS_SERVER_ADDRESS = "push.ios.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 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_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_Long_Port = "node_external_long_port";
public static final String HZ_Cluster_Node_External_Short_Port = "node_external_short_port"; public static final String HZ_Cluster_Node_External_Short_Port = "node_external_short_port";
@@ -101,25 +113,24 @@ public final class BrokerConstants {
public static final String HTTP_SERVER_SECRET_KEY = "http.admin.secret_key"; 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 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_SECRET_KEY = "token.key";
public static final String TOKEN_EXPIRE_TIME = "token.expire_time"; public static final String TOKEN_EXPIRE_TIME = "token.expire_time";
public static final String EMBED_DB_PROPERTY_NAME = "embed.db"; public static final String EMBED_DB_PROPERTY_NAME = "embed.db";
public static final String DB_AUTO_CLEAN_HISTORY_MESSAGES = "db.auto_clean_history_messages";
public static final String HZ_Cluster_Master_Node = "master_node";
public static final String SENSITIVE_Filter_Type = "sensitive.filter.type"; public static final String SENSITIVE_Filter_Type = "sensitive.filter.type";
public static final String SENSITIVE_Remote_Server_URL = "sensitive.remote_server_url";
public static final String SENSITIVE_Remote_Message_Type = "sensitive.remote_sensitive_message_type";
public static final String SENSITIVE_Remote_Fail_When_Matched = "sensitive.remote_fail_when_matched";
public static final String MESSAGE_Forward_Url = "message.forward.url"; public static final String MESSAGE_Forward_Url = "message.forward.url";
public static final String MESSAGE_Forward_Types = "message.forward.types";
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint"; public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification"; public static final String SERVER_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_ROAMING = "message.roaming";
public static final String MESSAGE_Remote_History_Message = "message.remote_history_message"; public static final String MESSAGE_Remote_History_Message = "message.remote_history_message";
@@ -140,6 +151,13 @@ public final class BrokerConstants {
public static final String CHATROOM_Participant_Idle_Time = "chatroom.participant_idle_time"; 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 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_DISABLE_REMOTE_SEARCH = "message.disable_remote_search";
public static final String MESSAGES_RECALL_TIME_LIMIT = "message.recall_time_limit"; public static final String MESSAGES_RECALL_TIME_LIMIT = "message.recall_time_limit";
@@ -27,9 +27,15 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
return ErrorCode.ERROR_CODE_GROUP_ALREADY_EXIST; 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); WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), isAdmin);
if (groupInfo != null) { 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()); sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").getCreateGroupNotifyContent(); 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) } else if (isAdmin || (groupInfo.getType() == ProtoConstants.GroupType.GroupType_Normal || groupInfo.getType() == ProtoConstants.GroupType.GroupType_Restricted)
&& groupInfo.getOwner() != null && groupInfo.getOwner().equals(fromUser)) { && 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 //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()); sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, null, "").getDismissGroupNotifyContent(); 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) { public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.PullUserRequest request, Qos1PublishHandler.IMCallback callback) {
WFCMessage.PullUserResult.Builder resultBuilder = WFCMessage.PullUserResult.newBuilder(); 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) { if (errorCode == ERROR_CODE_SUCCESS) {
byte[] data = resultBuilder.build().toByteArray(); byte[] data = resultBuilder.build().toByteArray();
ackPayload.ensureWritable(data.length).writeBytes(data); ackPayload.ensureWritable(data.length).writeBytes(data);
@@ -13,10 +13,15 @@ import cn.wildfirechat.proto.WFCMessage;
import win.liyufan.im.MessageShardingUtil; import win.liyufan.im.MessageShardingUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
abstract public class GroupHandler<T> extends IMHandler<T> { abstract public class GroupHandler<T> extends IMHandler<T> {
protected void sendGroupNotification(String fromUser, String targetId, List<Integer> lines, WFCMessage.MessageContent content) { 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) { if (lines == null) {
lines = new ArrayList<>(); lines = new ArrayList<>();
} else { } else {
@@ -32,10 +37,13 @@ abstract public class GroupHandler<T> extends IMHandler<T> {
WFCMessage.Message.Builder builder = WFCMessage.Message.newBuilder().setContent(content).setServerTimestamp(timestamp); 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.setConversation(builder.getConversationBuilder().setType(ProtoConstants.ConversationType.ConversationType_Group).setTarget(targetId).setLine(line));
builder.setFromUser(fromUser); builder.setFromUser(fromUser);
if(toUsers != null && !toUsers.isEmpty()) {
builder.addAllTo(toUsers);
}
try { try {
long messageId = MessageShardingUtil.generateId(); long messageId = MessageShardingUtil.generateId();
builder.setMessageId(messageId); builder.setMessageId(messageId);
saveAndPublish(fromUser, null, builder.build(), false); saveAndPublish(fromUser, null, builder.build());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -37,7 +37,7 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
builder.setMessageId(messageId); builder.setMessageId(messageId);
builder.setServerTimestamp(timestamp); builder.setServerTimestamp(timestamp);
saveAndPublish(request.getTargetUid(), null, builder.build(), false); saveAndPublish(request.getTargetUid(), null, builder.build());
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID); MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
String language = "zh_CN"; String language = "zh_CN";
@@ -60,7 +60,7 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
messageId = MessageShardingUtil.generateId(); messageId = MessageShardingUtil.generateId();
builder.setMessageId(messageId); builder.setMessageId(messageId);
saveAndPublish(request.getTargetUid(), null, builder.build(), false); saveAndPublish(request.getTargetUid(), null, builder.build());
if (m_messagesStore.isNewFriendWelcomeMessage()) { if (m_messagesStore.isNewFriendWelcomeMessage()) {
contentBuilder.setType(93); contentBuilder.setType(93);
@@ -73,7 +73,7 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
builder.setMessageId(messageId); builder.setMessageId(messageId);
timestamp = System.currentTimeMillis(); timestamp = System.currentTimeMillis();
builder.setServerTimestamp(timestamp); builder.setServerTimestamp(timestamp);
saveAndPublish(request.getTargetUid(), null, builder.build(), false); saveAndPublish(request.getTargetUid(), null, builder.build());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -34,10 +34,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection; import java.util.*;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_OVER_FREQUENCY; import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_OVER_FREQUENCY;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS; import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
@@ -207,8 +204,9 @@ abstract public class IMHandler<T> {
errorCode = ErrorCode.ERROR_CODE_SERVER_ERROR; errorCode = ErrorCode.ERROR_CODE_SERVER_ERROR;
} }
} }
if(errorCode != ErrorCode.INVALID_ASYNC_HANDLING) {
response(ackPayload, errorCode, callback); response(ackPayload, errorCode, callback);
}
} else { } else {
LOG.error("Handler {} preAction failure", this.getClass().getName()); LOG.error("Handler {} preAction failure", this.getClass().getName());
ByteBuf ackPayload = Unpooled.buffer(1); ByteBuf ackPayload = Unpooled.buffer(1);
@@ -239,17 +237,17 @@ abstract public class IMHandler<T> {
Set<String> notifyReceivers = new LinkedHashSet<>(); Set<String> notifyReceivers = new LinkedHashSet<>();
WFCMessage.Message.Builder messageBuilder = message.toBuilder(); 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)); mServer.getImBusinessScheduler().execute(() -> this.publisher.publish2Receivers(messageBuilder.build(), notifyReceivers, clientID, pullType));
return notifyReceivers.size(); 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<>(); Set<String> notifyReceivers = new LinkedHashSet<>();
message = m_messagesStore.storeMessage(username, clientID, message); message = m_messagesStore.storeMessage(username, clientID, message);
WFCMessage.Message.Builder messageBuilder = message.toBuilder(); 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)); mServer.getImBusinessScheduler().execute(() -> this.publisher.publish2Receivers(messageBuilder.build(), notifyReceivers, clientID, pullType));
return notifyReceivers.size(); return notifyReceivers.size();
} }
@@ -268,4 +266,13 @@ abstract public class IMHandler<T> {
mServer.getImBusinessScheduler().execute(() -> publisher.publish2Receivers(updatedMessage, notifyReceivers, clientID, ProtoConstants.PullType.Pull_Normal)); mServer.getImBusinessScheduler().execute(() -> publisher.publish2Receivers(updatedMessage, notifyReceivers, clientID, ProtoConstants.PullType.Pull_Normal));
return notifyReceivers.size(); 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.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import java.util.Set;
import static win.liyufan.im.IMTopic.KickoffGroupMemberTopic; import static win.liyufan.im.IMTopic.KickoffGroupMemberTopic;
@Handler(value = 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)) { if (!isAllow && (groupInfo.getType() == ProtoConstants.GroupType.GroupType_Normal || groupInfo.getType() == ProtoConstants.GroupType.GroupType_Restricted)) {
errorCode = ErrorCode.ERROR_CODE_NOT_RIGHT; errorCode = ErrorCode.ERROR_CODE_NOT_RIGHT;
} else { } 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 //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()); sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getRemovedMemberList()).getKickokfMemberGroupNotifyContent(); WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getRemovedMemberList()).getKickokfMemberGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content); 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()); 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> { public class ModifyGroupAliasHandler extends GroupHandler<WFCMessage.ModifyGroupMemberAlias> {
@Override @Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupMemberAlias request, Qos1PublishHandler.IMCallback callback) { 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(), null, isAdmin); ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias(), null, isAdmin);
if (errorCode == ERROR_CODE_SUCCESS && request.hasNotifyContent()) { 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()); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getAlias(), "").getModifyGroupMemberAliasNotifyContent(); 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> { public class ModifyGroupInfoHandler extends GroupHandler<WFCMessage.ModifyGroupInfoRequest> {
@Override @Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupInfoRequest request, Qos1PublishHandler.IMCallback callback) { 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); ErrorCode errorCode= m_messagesStore.modifyGroupInfo(fromUser, request.getGroupId(), request.getType(), request.getValue(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) { 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()); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = null; WFCMessage.MessageContent content = null;
@@ -21,9 +21,13 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
public class ModifyGroupMemberAliasHandler extends GroupHandler<WFCMessage.ModifyGroupMemberAlias> { public class ModifyGroupMemberAliasHandler extends GroupHandler<WFCMessage.ModifyGroupMemberAlias> {
@Override @Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupMemberAlias request, Qos1PublishHandler.IMCallback callback) { 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); ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias(), request.getMemberId(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS && request.hasNotifyContent()) { 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())) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent()); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getAlias(), request.getMemberId()).getModifyGroupMemberAliasNotifyContent(); WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getAlias(), request.getMemberId()).getModifyGroupMemberAliasNotifyContent();
@@ -14,20 +14,32 @@ import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import java.util.Set;
import static win.liyufan.im.IMTopic.QuitGroupTopic; import static win.liyufan.im.IMTopic.QuitGroupTopic;
@Handler(value = QuitGroupTopic) @Handler(value = QuitGroupTopic)
public class QuitGroupHandler extends GroupHandler<WFCMessage.QuitGroupRequest> { public class QuitGroupHandler extends GroupHandler<WFCMessage.QuitGroupRequest> {
@Override @Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.QuitGroupRequest request, Qos1PublishHandler.IMCallback callback) { 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()); ErrorCode errorCode = m_messagesStore.quitGroup(fromUser, request.getGroupId());
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) { 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()); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getQuitGroupNotifyContent(); WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getQuitGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content); 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; 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 cn.wildfirechat.proto.WFCMessage;
import com.hazelcast.core.Member; import com.hazelcast.core.Member;
import io.moquette.persistence.MemorySessionStore;
import io.moquette.spi.ClientSession; import io.moquette.spi.ClientSession;
import io.moquette.spi.impl.Qos1PublishHandler; import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf; 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> { public class RouteHandler extends IMHandler<WFCMessage.RouteRequest> {
@Override @Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.RouteRequest request, Qos1PublishHandler.IMCallback callback) { 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(); Member member = mServer.getHazelcastInstance().getCluster().getLocalMember();
String serverIp = member.getStringAttribute(HZ_Cluster_Node_External_IP); String serverIp = member.getStringAttribute(HZ_Cluster_Node_External_IP);
String longPort = member.getStringAttribute(HZ_Cluster_Node_External_Long_Port); String longPort = member.getStringAttribute(HZ_Cluster_Node_External_Long_Port);
@@ -8,32 +8,51 @@
package io.moquette.imhandler; package io.moquette.imhandler;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.hazelcast.util.StringUtil; import com.hazelcast.util.StringUtil;
import io.moquette.BrokerConstants; import io.moquette.BrokerConstants;
import io.moquette.spi.impl.Qos1PublishHandler; import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import io.netty.buffer.Unpooled;
import win.liyufan.im.HttpUtils;
import win.liyufan.im.IMTopic; import win.liyufan.im.IMTopic;
import win.liyufan.im.MessageShardingUtil; import win.liyufan.im.MessageShardingUtil;
import win.liyufan.im.Utility; import win.liyufan.im.Utility;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import static cn.wildfirechat.proto.ProtoConstants.ContentType.Text; import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
@Handler(value = IMTopic.SendMessageTopic) @Handler(value = IMTopic.SendMessageTopic)
public class SendMessageHandler extends IMHandler<WFCMessage.Message> { public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
private int mSensitiveType = 0; //命中敏感词时,0 失败,1 吞掉, 2 敏感词替换成*。 private int mSensitiveType = 0; //命中敏感词时,0 失败,1 吞掉, 2 敏感词替换成*。
private String mForwardUrl = null; private String mForwardUrl = null;
private Set<Integer> mForwardMessageTypes = new HashSet<>();
private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。 private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。
private String mRemoteSensitiveServerUrl = null;
private Set<Integer> mRemoteSensitiveMessageTypes;
private boolean mWaitRemoteSensitiveServerResponse = false;
public SendMessageHandler() { public SendMessageHandler() {
super(); super();
String forwardUrl = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_Url); String forwardUrl = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_Url);
if (!StringUtil.isNullOrEmpty(forwardUrl)) { if (!StringUtil.isNullOrEmpty(forwardUrl)) {
mForwardUrl = forwardUrl; mForwardUrl = forwardUrl;
String forwardTypes = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_Types);
if (!StringUtil.isNullOrEmpty(forwardTypes)) {
String[] tss = forwardTypes.split(",");
for (String ts:tss) {
mForwardMessageTypes.add(Integer.parseInt(ts.trim()));
}
}
} }
try { try {
@@ -49,6 +68,24 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e);
} }
try {
mRemoteSensitiveServerUrl = mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Server_URL);
if(!StringUtil.isNullOrEmpty(mRemoteSensitiveServerUrl)) {
mWaitRemoteSensitiveServerResponse = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Fail_When_Matched, "false"));
String types = mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Message_Type, "");
mRemoteSensitiveMessageTypes = new HashSet<>();
if(!StringUtil.isNullOrEmpty(types)) {
String[] ts = types.split(",");
for (String t:ts) {
mRemoteSensitiveMessageTypes.add(Integer.parseInt(t.trim()));
}
}
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
} }
@Override @Override
@@ -58,9 +95,14 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
boolean ignoreMsg = false; boolean ignoreMsg = false;
if (!isAdmin) { //admin do not check the right 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; return ErrorCode.INVALID_PARAMETER;
} }
if(m_messagesStore.getClientForbiddenSendTypes().contains(message.getContent().getType())) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
int userStatus = m_messagesStore.getUserStatus(fromUser); int userStatus = m_messagesStore.getUserStatus(fromUser);
if (userStatus == ProtoConstants.UserStatus.Muted || userStatus == ProtoConstants.UserStatus.Forbidden) { if (userStatus == ProtoConstants.UserStatus.Muted || userStatus == ProtoConstants.UserStatus.Forbidden) {
return ErrorCode.ERROR_CODE_FORBIDDEN_SEND_MSG; return ErrorCode.ERROR_CODE_FORBIDDEN_SEND_MSG;
@@ -100,7 +142,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
} }
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
long messageId = 0; final long messageId;
try { try {
messageId = MessageShardingUtil.generateId(); messageId = MessageShardingUtil.generateId();
} catch (Exception e) { } catch (Exception e) {
@@ -109,34 +151,101 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
} }
message = message.toBuilder().setFromUser(fromUser).setMessageId(messageId).setServerTimestamp(timestamp).build(); message = message.toBuilder().setFromUser(fromUser).setMessageId(messageId).setServerTimestamp(timestamp).build();
if (mForwardUrl != null) { if (mForwardUrl != null && (mForwardMessageTypes.isEmpty() || mForwardMessageTypes.contains(message.getContent().getType()))) {
publisher.forwardMessage(message, mForwardUrl); publisher.forwardMessage(message, mForwardUrl);
} }
if (!isAdmin) { if (!isAdmin) {
Set<String> matched = m_messagesStore.handleSensitiveWord(message.getContent().getSearchableContent()); if(StringUtil.isNullOrEmpty(mRemoteSensitiveServerUrl)) {
if (matched != null && !matched.isEmpty()) { Set<String> matched = m_messagesStore.handleSensitiveWord(message.getContent().getSearchableContent());
m_messagesStore.storeSensitiveMessage(message); if (matched != null && !matched.isEmpty()) {
if (mSensitiveType == 0) { m_messagesStore.storeSensitiveMessage(message);
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED; if (mSensitiveType == 0) {
} else if(mSensitiveType == 1) { errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
ignoreMsg = true; } else if (mSensitiveType == 1) {
} else if(mSensitiveType == 2) { ignoreMsg = true;
String text = message.getContent().getSearchableContent(); } else if (mSensitiveType == 2) {
for (String word : matched) { String text = message.getContent().getSearchableContent();
text = text.replace(word, "***"); for (String word : matched) {
text = text.replace(word, "***");
}
message = message.toBuilder().setContent(message.getContent().toBuilder().setSearchableContent(text).build()).build();
} }
}
} else {
if(mRemoteSensitiveMessageTypes.contains(message.getContent().getType())) {
final WFCMessage.Message finalMsg = message;
publisher.forwardMessageWithCallback(message, mRemoteSensitiveServerUrl, new HttpUtils.HttpCallback() {
@Override
public void onSuccess(String content) {
if(StringUtil.isNullOrEmpty(content)) {
saveAndPublish(fromUser, clientID, finalMsg);
} else {
MessagePayload payload = new Gson().fromJson(content, MessagePayload.class);
if (payload != null && payload.getType() > 0) {
WFCMessage.Message newMsg = finalMsg.toBuilder().setContent(payload.toProtoMessageContent()).build();
saveAndPublish(fromUser, clientID, newMsg);
} else {
LOG.error("Response content {} from censor is invalid payload, ignore response and send original message", content);
saveAndPublish(fromUser, clientID, finalMsg);
}
}
if(mWaitRemoteSensitiveServerResponse) {
ByteBuf ackPayload = Unpooled.buffer(21);
ErrorCode errorCode = ERROR_CODE_SUCCESS;
ackPayload.writeByte(errorCode.getCode());
ackPayload.writeLong(messageId);
ackPayload.writeLong(timestamp);
callback.onIMHandled(ErrorCode.ERROR_CODE_SUCCESS, ackPayload);
}
}
message = message.toBuilder().setContent(message.getContent().toBuilder().setSearchableContent(text).build()).build(); @Override
} else if(mSensitiveType == 3) { public void onFailure(int statusCode, String errorMessage) {
ByteBuf ackPayload = null;
ErrorCode errorCode = ERROR_CODE_SUCCESS;
if(statusCode == 403) {
if(mWaitRemoteSensitiveServerResponse) {
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
ackPayload = Unpooled.buffer(1);
ackPayload.writeByte(errorCode.getCode());
}
} else {
LOG.warn("Failed to censor message with status {}, errorMessage {}. Send the original message", statusCode, errorMessage);
saveAndPublish(fromUser, clientID, finalMsg);
if(mWaitRemoteSensitiveServerResponse) {
errorCode = ERROR_CODE_SUCCESS;
ackPayload = Unpooled.buffer(21);
ackPayload.writeByte(errorCode.getCode());
ackPayload.writeLong(messageId);
ackPayload.writeLong(timestamp);
}
}
if(mWaitRemoteSensitiveServerResponse) {
callback.onIMHandled(errorCode, ackPayload);
}
}
});
if(mWaitRemoteSensitiveServerResponse) {
ackPayload.clear();
return ErrorCode.INVALID_ASYNC_HANDLING;
} else {
ackPayload = ackPayload.capacity(20);
ackPayload.writeLong(messageId);
ackPayload.writeLong(timestamp);
return ErrorCode.ERROR_CODE_SUCCESS;
}
} }
} }
} }
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) { if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
saveAndPublish(fromUser, clientID, message, ignoreMsg); if(!ignoreMsg) {
saveAndPublish(fromUser, clientID, message);
}
ackPayload = ackPayload.capacity(20); ackPayload = ackPayload.capacity(20);
ackPayload.writeLong(messageId); ackPayload.writeLong(messageId);
ackPayload.writeLong(timestamp); ackPayload.writeLong(timestamp);
@@ -21,9 +21,13 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
public class SetGroupManagerHandler extends GroupHandler<WFCMessage.SetGroupManagerRequest> { public class SetGroupManagerHandler extends GroupHandler<WFCMessage.SetGroupManagerRequest> {
@Override @Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.SetGroupManagerRequest request, Qos1PublishHandler.IMCallback callback) { 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); ErrorCode errorCode = m_messagesStore.setGroupManager(fromUser, request.getGroupId(), request.getType(), request.getUserIdList(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) { 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()); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getType() + "", request.getUserIdList()).getSetGroupManagerNotifyContent(); 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> { public class TransferGroupHandler extends GroupHandler<WFCMessage.TransferGroupRequest> {
@Override @Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.TransferGroupRequest request, Qos1PublishHandler.IMCallback callback) { 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); ErrorCode errorCode = m_messagesStore.transferGroup(fromUser, request.getGroupId(), request.getNewOwner(), isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) { 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()); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getNewOwner()).getTransferGroupNotifyContent(); WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getNewOwner()).getTransferGroupNotifyContent();
@@ -8,6 +8,7 @@
package io.moquette.persistence; package io.moquette.persistence;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.pojos.SystemSettingPojo; import cn.wildfirechat.pojos.SystemSettingPojo;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
@@ -32,6 +33,7 @@ import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent; import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE; import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*; import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*;
@@ -72,7 +74,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -106,7 +108,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -146,7 +148,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -203,10 +205,9 @@ public class DatabaseStore {
} }
if (page > 0) { if (page > 0) {
sql += "offset = '" + page * 20 + "'"; sql += " offset " + page * 20;
} }
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
int index = 1; int index = 1;
@@ -286,7 +287,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -310,7 +311,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -368,7 +369,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -424,7 +425,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -483,7 +484,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -556,7 +557,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -607,7 +608,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -668,10 +669,10 @@ public class DatabaseStore {
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
try { try {
if (resultSet!=null) { if (resultSet!=null) {
@@ -679,14 +680,14 @@ public class DatabaseStore {
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} }
} }
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, null); DBUtil.closeDB(connection, null);
} }
@@ -724,7 +725,7 @@ public class DatabaseStore {
} }
} catch (SQLException | IOException e) { } catch (SQLException | IOException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, resultSet); DBUtil.closeDB(connection, statement, resultSet);
} }
@@ -744,7 +745,7 @@ public class DatabaseStore {
LOG.info("Update rows {}", count); LOG.info("Update rows {}", count);
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -755,14 +756,22 @@ public class DatabaseStore {
long[] before = new long[1]; long[] before = new long[1];
before[0] = beforeUid; before[0] = beforeUid;
boolean hasMore = loadRemoteMessagesFromTable(user, conversation, before, count, MessageShardingUtil.getMessageTable(beforeUid), messages); boolean hasMore = loadRemoteMessagesFromTable(user, conversation, before, count, MessageShardingUtil.getMessageTable(beforeUid), messages);
if (messages.size() < count) { while (messages.size() < count && hasMore) {
if (hasMore) { hasMore = loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), MessageShardingUtil.getMessageTable(beforeUid), messages);
loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), MessageShardingUtil.getMessageTable(beforeUid), messages); }
} else {
String nexTable = MessageShardingUtil.getPreviousMessageTable(before[0]); int month = 0;
if (!StringUtil.isNullOrEmpty(nexTable)) { while (messages.size() < count && !DBUtil.IsEmbedDB && month++ < 24) {
loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), nexTable, messages); 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) { } catch (SQLException | IOException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, resultSet); DBUtil.closeDB(connection, statement, resultSet);
} }
@@ -869,7 +878,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -897,12 +906,12 @@ public class DatabaseStore {
statement = null; statement = null;
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} }
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -941,7 +950,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -978,7 +987,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1003,7 +1012,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1059,7 +1068,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -1096,7 +1105,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1127,7 +1136,6 @@ public class DatabaseStore {
"`_type` = ?," + "`_type` = ?," +
"`_extra` = ?," + "`_extra` = ?," +
"`_dt` = ?," + "`_dt` = ?," +
"`_member_count` = ?," +
"`_mute` = ?" + "`_mute` = ?" +
", `_join_type` = ?" + ", `_join_type` = ?" +
", `_private_chat` = ?" + ", `_private_chat` = ?" +
@@ -1158,7 +1166,6 @@ public class DatabaseStore {
statement.setInt(index++, groupInfo.getType()); statement.setInt(index++, groupInfo.getType());
statement.setString(index++, groupInfo.getExtra()); statement.setString(index++, groupInfo.getExtra());
statement.setLong(index++, groupInfo.getUpdateDt() == 0 ? System.currentTimeMillis() : groupInfo.getUpdateDt()); statement.setLong(index++, groupInfo.getUpdateDt() == 0 ? System.currentTimeMillis() : groupInfo.getUpdateDt());
statement.setInt(index++, groupInfo.getMemberCount());
statement.setInt(index++, groupInfo.getMute()); statement.setInt(index++, groupInfo.getMute());
statement.setInt(index++, groupInfo.getJoinType()); statement.setInt(index++, groupInfo.getJoinType());
statement.setInt(index++, groupInfo.getPrivateChat()); statement.setInt(index++, groupInfo.getPrivateChat());
@@ -1169,7 +1176,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1212,7 +1219,7 @@ public class DatabaseStore {
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, resultSet); DBUtil.closeDB(connection, statement, resultSet);
} }
@@ -1234,7 +1241,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1274,7 +1281,7 @@ public class DatabaseStore {
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, resultSet); DBUtil.closeDB(connection, statement, resultSet);
} }
@@ -1307,7 +1314,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1346,7 +1353,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1374,7 +1381,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1401,7 +1408,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1492,7 +1499,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1542,7 +1549,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1583,7 +1590,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1596,12 +1603,10 @@ public class DatabaseStore {
ResultSet rs = null; ResultSet rs = null;
try { try {
connection = DBUtil.getConnection(); 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 = connection.prepareStatement(sql);
statement.setString(1, userId); statement.setString(1, userId);
statement.setInt(2, ProtoConstants.GroupMemberType.GroupMemberType_Removed);
rs = statement.executeQuery(); rs = statement.executeQuery();
Set<String> out = new HashSet<>(); Set<String> out = new HashSet<>();
@@ -1613,31 +1618,23 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
return null; return null;
} }
void updateGroupMemberCountDt(final String groupId, final int count, final long dt) {
void updateGroupMemberDt(final String groupId, final long dt) {
Connection connection = null; Connection connection = null;
PreparedStatement statement = null; PreparedStatement statement = null;
try { try {
connection = DBUtil.getConnection(); connection = DBUtil.getConnection();
String sql ; String sql = "update t_group set `_member_dt` = ?, `_dt` = ? where `_gid` = ?";
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` = ?";
}
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
int index = 1; int index = 1;
if (count >=0) {
statement.setInt(index++, count);
}
statement.setLong(index++, dt); statement.setLong(index++, dt);
statement.setLong(index++, dt); statement.setLong(index++, dt);
statement.setString(index++, groupId); statement.setString(index++, groupId);
@@ -1647,7 +1644,30 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); 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 { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1706,7 +1726,7 @@ public class DatabaseStore {
} }
} }
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1715,11 +1735,8 @@ public class DatabaseStore {
int removeGroupMember(String groupId, List<String> groupMembers) { int removeGroupMember(String groupId, List<String> groupMembers) {
Connection connection = null; Connection connection = null;
PreparedStatement statement = null; PreparedStatement statement = null;
PreparedStatement statement2 = null;
try { try {
connection = DBUtil.getConnection(); connection = DBUtil.getConnection();
connection.setAutoCommit(false);
StringBuilder sqlBuilder = new StringBuilder("update t_group_member set `_type` = ?, `_dt` = ? where `_mid` in ("); StringBuilder sqlBuilder = new StringBuilder("update t_group_member set `_type` = ?, `_dt` = ? where `_mid` in (");
for (int i = 0; i < groupMembers.size(); i++) { for (int i = 0; i < groupMembers.size(); i++) {
sqlBuilder.append("?"); sqlBuilder.append("?");
@@ -1728,9 +1745,7 @@ public class DatabaseStore {
} }
} }
sqlBuilder.append(")"); sqlBuilder.append(")");
sqlBuilder.append(" and _gid = ?"); sqlBuilder.append(" and _gid = ?");
statement = connection.prepareStatement(sqlBuilder.toString()); statement = connection.prepareStatement(sqlBuilder.toString());
int index = 1; int index = 1;
@@ -1742,36 +1757,14 @@ public class DatabaseStore {
statement.setString(index++, memberId); statement.setString(index++, memberId);
} }
statement.setString(index++, groupId); statement.setString(index++, groupId);
int count = statement.executeUpdate(); int count = statement.executeUpdate();
LOG.info("Update rows {}", count); 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) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
if (connection != null) {
try {
connection.commit();
connection.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
DBUtil.closeDB(connection, statement2);
} }
return 0; return 0;
} }
@@ -1855,7 +1848,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -1907,7 +1900,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1931,7 +1924,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -1997,7 +1990,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2031,7 +2024,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2054,7 +2047,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2076,7 +2069,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2132,7 +2125,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2184,7 +2177,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2211,7 +2204,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2291,7 +2284,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
throw new Exception(e.getMessage()); throw new Exception(e.getMessage());
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
@@ -2312,7 +2305,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2347,7 +2340,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2372,7 +2365,7 @@ public class DatabaseStore {
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} }
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
@@ -2387,7 +2380,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
return -1; return -1;
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
@@ -2470,6 +2463,8 @@ public class DatabaseStore {
builder.setDeleted(deleted); builder.setDeleted(deleted);
long longValue = rs.getLong(index++); long longValue = rs.getLong(index++);
if(longValue <= 0)
longValue = 1;
builder.setUpdateDt(longValue); builder.setUpdateDt(longValue);
return builder.build(); return builder.build();
@@ -2477,7 +2472,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2500,7 +2495,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2523,7 +2518,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2551,7 +2546,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2588,7 +2583,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2613,7 +2608,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2635,7 +2630,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2704,7 +2699,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -2734,7 +2729,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2773,7 +2768,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2812,7 +2807,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2833,7 +2828,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2854,7 +2849,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2921,7 +2916,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -2944,7 +2939,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -3024,7 +3019,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -3072,7 +3067,7 @@ public class DatabaseStore {
} }
} }
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -3103,7 +3098,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -3138,10 +3133,9 @@ public class DatabaseStore {
if (page > 0) { if (page > 0) {
sql += "offset = '" + page * 20 + "'"; sql += " offset " + page * 20;
} }
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
int index = 1; int index = 1;
if (buzzy) { if (buzzy) {
@@ -3190,7 +3184,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -3234,7 +3228,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -3261,7 +3255,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement, rs); DBUtil.closeDB(connection, statement, rs);
} }
@@ -3285,7 +3279,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -3308,7 +3302,7 @@ public class DatabaseStore {
} catch (SQLException e) { } catch (SQLException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e, RDBS_Exception);
} finally { } finally {
DBUtil.closeDB(connection, statement); DBUtil.closeDB(connection, statement);
} }
@@ -16,14 +16,14 @@
package io.moquette.persistence; package io.moquette.persistence;
import cn.wildfirechat.pojos.SystemSettingPojo; import cn.wildfirechat.pojos.*;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import com.hazelcast.core.*; import com.hazelcast.core.*;
import com.hazelcast.util.StringUtil; import com.hazelcast.util.StringUtil;
import com.xiaoleilu.loServer.model.FriendData; import com.xiaoleilu.loServer.model.FriendData;
import cn.wildfirechat.pojos.InputOutputUserBlockStatus;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import io.moquette.BrokerConstants; import io.moquette.BrokerConstants;
import io.moquette.imhandler.IMHandler; import io.moquette.imhandler.IMHandler;
@@ -39,11 +39,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import win.liyufan.im.*; import win.liyufan.im.*;
import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -52,16 +47,23 @@ import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
import static cn.wildfirechat.proto.ProtoConstants.ChannelState.Channel_State_Mask_Deleted; import static cn.wildfirechat.proto.ProtoConstants.ChannelState.Channel_State_Mask_Deleted;
import static cn.wildfirechat.proto.ProtoConstants.ChannelUpdateEventType.*;
import static cn.wildfirechat.proto.ProtoConstants.ChatroomMemberUpdateEventType.Chatroom_Member_Event_Join;
import static cn.wildfirechat.proto.ProtoConstants.ChatroomMemberUpdateEventType.Chatroom_Member_Event_Leave;
import static cn.wildfirechat.proto.ProtoConstants.ChatroomUpdateEventType.Chatroom_Event_Create;
import static cn.wildfirechat.proto.ProtoConstants.ChatroomUpdateEventType.Chatroom_Event_Destroy;
import static cn.wildfirechat.proto.ProtoConstants.GroupMemberType.*; import static cn.wildfirechat.proto.ProtoConstants.GroupMemberType.*;
import static cn.wildfirechat.proto.ProtoConstants.ModifyChannelInfoType.*; import static cn.wildfirechat.proto.ProtoConstants.ModifyChannelInfoType.*;
import static cn.wildfirechat.proto.ProtoConstants.ModifyGroupInfoType.*; import static cn.wildfirechat.proto.ProtoConstants.ModifyGroupInfoType.*;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent; import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
import static cn.wildfirechat.proto.ProtoConstants.Platform.*; import static cn.wildfirechat.proto.ProtoConstants.Platform.*;
import static cn.wildfirechat.proto.ProtoConstants.UpdateUserInfoMask.*;
import static io.moquette.BrokerConstants.*; import static io.moquette.BrokerConstants.*;
import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE; import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE;
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE; import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
import static win.liyufan.im.MyInfoType.*; import static cn.wildfirechat.pojos.MyInfoType.*;
import static win.liyufan.im.UserSettingScope.kUserSettingPCOnline; import static win.liyufan.im.UserSettingScope.kUserSettingPCOnline;
public class MemoryMessagesStore implements IMessagesStore { public class MemoryMessagesStore implements IMessagesStore {
@@ -136,8 +138,22 @@ public class MemoryMessagesStore implements IMessagesStore {
private long mChatroomParticipantIdleTime = 900000; private long mChatroomParticipantIdleTime = 900000;
private boolean mChatroomRejoinWhenActive = true; private boolean mChatroomRejoinWhenActive = true;
private List<Integer> mForbiddenClientSendTypes = new ArrayList<>();
private long mRecallTimeLimit = 300; private long mRecallTimeLimit = 300;
private String mGroupInfoUpdateCallback;
private String mGroupMemberUpdateCallback;
private String mRelationUpdateCallback;
private String mUserInfoUpdateCallback;
private String mChannelInfoUpdateCallback;
private String mChatroomInfoUpdateCallback;
private String mChatroomMemberUpdateCallback;
private boolean mGroupAllowClientCustomOperationNotification;
private int mGroupVisibleQuitKickoffNotification;
private Set<Integer> mUserHideProperties = new HashSet<>();
MemoryMessagesStore(Server server, DatabaseStore databaseStore) { MemoryMessagesStore(Server server, DatabaseStore databaseStore) {
m_Server = server; m_Server = server;
this.databaseStore = databaseStore; this.databaseStore = databaseStore;
@@ -243,6 +259,95 @@ public class MemoryMessagesStore implements IMessagesStore {
mRecallTimeLimit = Long.parseLong(m_Server.getConfig().getProperty(BrokerConstants.MESSAGES_RECALL_TIME_LIMIT)); mRecallTimeLimit = Long.parseLong(m_Server.getConfig().getProperty(BrokerConstants.MESSAGES_RECALL_TIME_LIMIT));
} catch (Exception e) { } catch (Exception e) {
} }
try {
String strTypes = m_Server.getConfig().getProperty(BrokerConstants.MESSAGES_FORBIDDEN_CLIENT_SEND_TYPES);
if(!StringUtil.isNullOrEmpty(strTypes)) {
for (String strType:strTypes.split(",")) {
try {
int type = Integer.parseInt(strType);
mForbiddenClientSendTypes.add(type);
} catch (NumberFormatException e) {
}
}
}
} catch (Exception e) {
}
try {
mGroupInfoUpdateCallback = server.getConfig().getProperty(GROUP_INFO_UPDATE_CALLBACK);
} catch (Exception e) {
}
try {
mGroupMemberUpdateCallback = server.getConfig().getProperty(GROUP_MEMBER_UPDATE_CALLBACK);
} catch (Exception e) {
}
try {
mRelationUpdateCallback = server.getConfig().getProperty(RELATION_UPDATE_CALLBACK);
} catch (Exception e) {
}
try {
mUserInfoUpdateCallback = server.getConfig().getProperty(USER_INFO_UPDATE_CALLBACK);
} catch (Exception e) {
}
try {
mChannelInfoUpdateCallback = server.getConfig().getProperty(CHANNEL_INFO_UPDATE_CALLBACK);
} catch (Exception e) {
}
try {
mChatroomInfoUpdateCallback = server.getConfig().getProperty(CHATROOM_INFO_UPDATE_CALLBACK);
} catch (Exception e) {
}
try {
mChatroomMemberUpdateCallback = server.getConfig().getProperty(CHATROOM_MEMBER_UPDATE_CALLBACK);
} catch (Exception e) {
}
try {
mGroupAllowClientCustomOperationNotification = Boolean.parseBoolean(server.getConfig().getProperty(GROUP_Allow_Client_Custom_Operation_Notification));
} catch (Exception e) {
}
try {
mGroupVisibleQuitKickoffNotification = Integer.parseInt(server.getConfig().getProperty(GROUP_Visible_Quit_Kickoff_Notification, "0"));
} catch (Exception e) {
}
try {
String userHideStr = server.getConfig().getProperty(USER_HIDE_PROPERTIES);
if(!StringUtil.isNullOrEmpty(userHideStr)) {
String[] proStrs = userHideStr.split(",");
for (String proStr:proStrs) {
int value = Integer.parseInt(proStr);
if(value > 1 && value < 9) {
mUserHideProperties.add(value);
}
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
} }
private void printMissConfigLog(String config, String defaultValue) { private void printMissConfigLog(String config, String defaultValue) {
@@ -302,24 +407,12 @@ public class MemoryMessagesStore implements IMessagesStore {
@Override @Override
public int getNotifyReceivers(String fromUser, WFCMessage.Message.Builder messageBuilder, Set<String> notifyReceivers, boolean ignoreMsg) { public int getNotifyReceivers(String fromUser, WFCMessage.Message.Builder messageBuilder, Set<String> notifyReceivers) {
WFCMessage.Message message = messageBuilder.build(); WFCMessage.Message message = messageBuilder.build();
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
int type = message.getConversation().getType(); int type = message.getConversation().getType();
int pullType = ProtoConstants.PullType.Pull_Normal; int pullType = ProtoConstants.PullType.Pull_Normal;
if (ignoreMsg) {
if (type == ProtoConstants.ConversationType.ConversationType_ChatRoom) {
pullType = ProtoConstants.PullType.Pull_ChatRoom;
}
if (message.getContent().getPersistFlag() != Transparent) {
notifyReceivers.add(fromUser);
}
return pullType;
}
if (type == ProtoConstants.ConversationType.ConversationType_Private) { if (type == ProtoConstants.ConversationType.ConversationType_Private) {
notifyReceivers.add(fromUser); notifyReceivers.add(fromUser);
notifyReceivers.add(message.getConversation().getTarget()); notifyReceivers.add(message.getConversation().getTarget());
@@ -399,10 +492,10 @@ public class MemoryMessagesStore implements IMessagesStore {
LOG.error("Channel not exist"); LOG.error("Channel not exist");
} }
} }
//
if (message.getContent().getPersistFlag() == Transparent) { // if (message.getContent().getPersistFlag() == Transparent) {
notifyReceivers.remove(fromUser); // notifyReceivers.remove(fromUser);
} // }
return pullType; return pullType;
} }
@@ -473,9 +566,13 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
boolean noRoaming = false; boolean noRoaming = false;
if (pullType == ProtoConstants.PullType.Pull_Normal && fromMessageId == 0 && !IS_MESSAGE_ROAMING) { if (pullType == ProtoConstants.PullType.Pull_Normal && fromMessageId == 0) {
noRoaming = true; if(!IS_MESSAGE_ROAMING) {
noRoaming = true;
}
session.setPullHistoryMsg(true);
} }
while (true) { while (true) {
Map.Entry<Long, Long> entry = maps.higherEntry(current); Map.Entry<Long, Long> entry = maps.higherEntry(current);
if (entry == null) { if (entry == null) {
@@ -487,7 +584,7 @@ public class MemoryMessagesStore implements IMessagesStore {
MessageBundle bundle = mIMap.get(targetMessageId); MessageBundle bundle = mIMap.get(targetMessageId);
if (bundle != null) { if (bundle != null) {
if (exceptClientId == null || !exceptClientId.equals(bundle.getFromClientId()) || !user.equals(bundle.getFromUser())) { if (exceptClientId == null || session.isPullHistoryMsg() || !exceptClientId.equals(bundle.getFromClientId()) || !user.equals(bundle.getFromUser())) {
if (pullType == ProtoConstants.PullType.Pull_ChatRoom) { if (pullType == ProtoConstants.PullType.Pull_ChatRoom) {
if (!bundle.getMessage().getConversation().getTarget().equals(chatroomId)) { if (!bundle.getMessage().getConversation().getTarget().equals(chatroomId)) {
@@ -521,6 +618,9 @@ public class MemoryMessagesStore implements IMessagesStore {
if (lastEntry != null) { if (lastEntry != null) {
head = lastEntry.getKey(); head = lastEntry.getKey();
} }
if (pullType == ProtoConstants.PullType.Pull_Normal && current == head) {
session.setPullHistoryMsg(false);
}
} finally { } finally {
mReadLock.unlock(); mReadLock.unlock();
} }
@@ -796,9 +896,11 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
List<WFCMessage.GroupMember> updatedMemberList = new ArrayList<>(); List<WFCMessage.GroupMember> updatedMemberList = new ArrayList<>();
boolean hasOwnerMember = false;
for (WFCMessage.GroupMember member : memberList) { for (WFCMessage.GroupMember member : memberList) {
if (member.getMemberId().equals(owner)) { if (member.getMemberId().equals(owner)) {
member = member.toBuilder().setUpdateDt(dt).setCreateDt(dt).setType(ProtoConstants.GroupMemberType.GroupMemberType_Owner).build(); member = member.toBuilder().setUpdateDt(dt).setCreateDt(dt).setType(ProtoConstants.GroupMemberType.GroupMemberType_Owner).build();
hasOwnerMember = true;
} else { } else {
member = member.toBuilder().setUpdateDt(dt).setCreateDt(dt).build(); member = member.toBuilder().setUpdateDt(dt).setCreateDt(dt).build();
} }
@@ -807,6 +909,12 @@ public class MemoryMessagesStore implements IMessagesStore {
dt++; dt++;
} }
if(!hasOwnerMember && !StringUtil.isNullOrEmpty(owner)) {
WFCMessage.GroupMember member = WFCMessage.GroupMember.newBuilder().setMemberId(owner).setUpdateDt(dt).setCreateDt(dt).setType(ProtoConstants.GroupMemberType.GroupMemberType_Owner).build();
groupMembers.put(groupId, member);
updatedMemberList.add(member);
}
groupInfo = groupInfo.toBuilder() groupInfo = groupInfo.toBuilder()
.setTargetId(groupId) .setTargetId(groupId)
.setName(groupInfo.getName()) .setName(groupInfo.getName())
@@ -815,17 +923,136 @@ public class MemoryMessagesStore implements IMessagesStore {
.setExtra(groupInfo.getExtra()) .setExtra(groupInfo.getExtra())
.setUpdateDt(dt) .setUpdateDt(dt)
.setMemberUpdateDt(dt) .setMemberUpdateDt(dt)
.setMemberCount(memberList.size()) .setMemberCount(updatedMemberList.size())
.setOwner(owner) .setOwner(owner)
.build(); .build();
mIMap.set(groupId, groupInfo); mIMap.set(groupId, groupInfo);
databaseStore.persistGroupMember(groupId, updatedMemberList); databaseStore.persistGroupMember(groupId, updatedMemberList);
callbackGroupEvent(fromUser, groupInfo.getTargetId(), ProtoConstants.GroupUpdateEventType.Group_Event_Create);
return groupInfo; return groupInfo;
} }
private void callbackGroupEvent(String operatorId, String groupId, int type) {
if (!StringUtil.isNullOrEmpty(mGroupInfoUpdateCallback)) {
GroupUpdateEvent event = new GroupUpdateEvent();
event.operatorId = operatorId;
event.groupId = groupId;
event.type = type;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mGroupInfoUpdateCallback, new Gson().toJson(event));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
private void callbackGroupMemberEvent(String operatorId, String groupId, List<String> memberIds, int type, String value) {
if (!StringUtil.isNullOrEmpty(mGroupMemberUpdateCallback)) {
GroupMemberUpdateEvent event = new GroupMemberUpdateEvent();
event.operatorId = operatorId;
event.groupId = groupId;
event.memberIds = memberIds;
event.type = type;
event.value = value;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mGroupMemberUpdateCallback, new Gson().toJson(event));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
private void callbackRelationEvent(String userId, String targetId, int type, String value) {
if (!StringUtil.isNullOrEmpty(mRelationUpdateCallback)) {
RelationUpdateEvent event = new RelationUpdateEvent();
event.userId = userId;
event.targetId = targetId;
event.type = type;
event.value = value;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mRelationUpdateCallback, new Gson().toJson(event));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
private void callbackUserInfoEvent(WFCMessage.User user) {
if (!StringUtil.isNullOrEmpty(mUserInfoUpdateCallback)) {
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mUserInfoUpdateCallback, new Gson().toJson(InputOutputUserInfo.fromPbUser(user)));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
private void callbackChannelInfoUpdateEvent(String operatorId, String channelId, int type) {
if (!StringUtil.isNullOrEmpty(mChannelInfoUpdateCallback)) {
ChannelUpdateEvent event = new ChannelUpdateEvent();
event.operatorId = operatorId;
event.channelId = channelId;
event.type = type;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mChannelInfoUpdateCallback, new Gson().toJson(event));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
private void callbackChatroomInfoUpdateEvent(String chatroomId, int type) {
if (!StringUtil.isNullOrEmpty(mChatroomInfoUpdateCallback)) {
ChatroomUpdateEvent event = new ChatroomUpdateEvent();
event.chatroomId = chatroomId;
event.type = type;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mChatroomInfoUpdateCallback, new Gson().toJson(event));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
private void callbackChatroomMemberEvent(String operatorId, String chatroomId, List<String> memberIds, int type) {
if (!StringUtil.isNullOrEmpty(mChatroomMemberUpdateCallback)) {
ChatroomMemberUpdateEvent event = new ChatroomMemberUpdateEvent();
event.operatorId = operatorId;
event.chatroomId = chatroomId;
event.memberIds = memberIds;
event.type = type;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mChatroomMemberUpdateCallback, new Gson().toJson(event));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
@Override @Override
public ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList) { public ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
@@ -920,26 +1147,20 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
for (WFCMessage.GroupMember member : members) {
if (newInviteUsers.contains(member.getMemberId())) {
groupMembers.remove(groupId, member);
}
}
for (WFCMessage.GroupMember member : memberList) {
groupMembers.put(groupId, member);
}
int count = 0;
for (WFCMessage.GroupMember member : groupMembers.get(groupId)) {
if (member.getType() != GroupMemberType_Removed) {
count++;
}
}
mIMap.put(groupId, groupInfo.toBuilder().setMemberUpdateDt(updateDt).setUpdateDt(updateDt).setMemberCount(count).build());
databaseStore.persistGroupMember(groupId, memberList); databaseStore.persistGroupMember(groupId, memberList);
databaseStore.updateGroupMemberCountDt(groupId, count, updateDt); databaseStore.updateGroupMemberCountDt(groupId);
groupMembers.remove(groupId);
mIMap.evict(groupId);
List<String> memberIds = new ArrayList<>();
for (WFCMessage.GroupMember member : memberList) {
if (member.getType() != GroupMemberType_Removed) {
memberIds.add(member.getMemberId());
}
}
callbackGroupMemberEvent(operator, groupId, memberIds, ProtoConstants.GroupMemberUpdateEventType.Group_Member_Event_Join, null);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -948,18 +1169,20 @@ public class MemoryMessagesStore implements IMessagesStore {
removeGroupMember(groupId, memberList); removeGroupMember(groupId, memberList);
removeFavGroup(groupId, memberList); removeFavGroup(groupId, memberList);
removeGroupUserSettings(groupId, memberList); removeGroupUserSettings(groupId, memberList);
callbackGroupMemberEvent(operator, groupId, memberList, ProtoConstants.GroupMemberUpdateEventType.Group_Member_Event_Kickoff, null);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
void removeGroupMember(String groupId, List<String> memberIds) { void removeGroupMember(String groupId, List<String> memberIds) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
databaseStore.removeGroupMember(groupId, memberIds); databaseStore.removeGroupMember(groupId, memberIds);
databaseStore.updateGroupMemberCountDt(groupId);
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS); MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
groupMembers.remove(groupId); groupMembers.remove(groupId);
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP); IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
mIMap.evict(groupId); mIMap.evict(groupId);
} }
void removeFavGroup(String groupId, List<String> memberIds) { void removeFavGroup(String groupId, List<String> memberIds) {
@@ -1026,6 +1249,8 @@ public class MemoryMessagesStore implements IMessagesStore {
removeGroupMember(groupId, Arrays.asList(operator)); removeGroupMember(groupId, Arrays.asList(operator));
removeFavGroup(groupId, Arrays.asList(operator)); removeFavGroup(groupId, Arrays.asList(operator));
removeGroupUserSettings(groupId, Arrays.asList(operator)); removeGroupUserSettings(groupId, Arrays.asList(operator));
callbackGroupMemberEvent(operator, groupId, Arrays.asList(operator), ProtoConstants.GroupMemberUpdateEventType.Group_Member_Event_Leave, null);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -1093,6 +1318,7 @@ public class MemoryMessagesStore implements IMessagesStore {
removeFavGroup(groupId, ids); removeFavGroup(groupId, ids);
removeGroupUserSettings(groupId, ids); removeGroupUserSettings(groupId, ids);
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Destroy);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -1144,8 +1370,6 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
WFCMessage.GroupInfo.Builder newInfoBuilder = oldInfo.toBuilder(); WFCMessage.GroupInfo.Builder newInfoBuilder = oldInfo.toBuilder();
if (modifyType == Modify_Group_Name) if (modifyType == Modify_Group_Name)
@@ -1167,7 +1391,18 @@ public class MemoryMessagesStore implements IMessagesStore {
newInfoBuilder.setUpdateDt(System.currentTimeMillis()); newInfoBuilder.setUpdateDt(System.currentTimeMillis());
mIMap.put(groupId, newInfoBuilder.build()); databaseStore.persistGroupInfo(newInfoBuilder.build());
mIMap.evict(groupId);
if (modifyType == Modify_Group_Mute) {
if (newInfoBuilder.getMute() > 0) {
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Mute);
} else {
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Unmute);
}
} else {
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Update);
}
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -1238,7 +1473,7 @@ public class MemoryMessagesStore implements IMessagesStore {
groupMembers.remove(groupId, member); groupMembers.remove(groupId, member);
member = member.toBuilder().setAlias(alias).setUpdateDt(updateDt).build(); member = member.toBuilder().setAlias(alias).setUpdateDt(updateDt).build();
databaseStore.persistGroupMember(groupId, Arrays.asList(member)); databaseStore.persistGroupMember(groupId, Arrays.asList(member));
databaseStore.updateGroupMemberCountDt(groupId, -1, updateDt); databaseStore.updateGroupMemberDt(groupId, updateDt);
groupMembers.put(groupId, member); groupMembers.put(groupId, member);
mIMap.set(groupId, groupInfo.toBuilder().setUpdateDt(updateDt).setMemberUpdateDt(updateDt).build()); mIMap.set(groupId, groupInfo.toBuilder().setUpdateDt(updateDt).setMemberUpdateDt(updateDt).build());
@@ -1252,6 +1487,7 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_NOT_IN_GROUP; return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
} }
callbackGroupMemberEvent(operator, groupId, Arrays.asList(memberId), ProtoConstants.GroupMemberUpdateEventType.Group_Member_Event_Alias, alias);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -1407,6 +1643,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Transfer);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -1440,11 +1677,12 @@ public class MemoryMessagesStore implements IMessagesStore {
member = member.toBuilder().setType(type == 0 ? ProtoConstants.GroupMemberType.GroupMemberType_Normal : ProtoConstants.GroupMemberType.GroupMemberType_Manager).setUpdateDt(updateDt).build(); member = member.toBuilder().setType(type == 0 ? ProtoConstants.GroupMemberType.GroupMemberType_Normal : ProtoConstants.GroupMemberType.GroupMemberType_Manager).setUpdateDt(updateDt).build();
databaseStore.persistGroupMember(groupId, Arrays.asList(member)); databaseStore.persistGroupMember(groupId, Arrays.asList(member));
groupMembers.put(groupId, member); groupMembers.put(groupId, member);
// userList.remove(member.getMemberId());
} }
} }
databaseStore.persistGroupInfo(groupInfo.toBuilder().setUpdateDt(updateDt).setMemberUpdateDt(updateDt).build());
mIMap.evict(groupId);
mIMap.put(groupId, groupInfo.toBuilder().setUpdateDt(updateDt).setMemberUpdateDt(updateDt).build()); callbackGroupMemberEvent(operator, groupId, userList, ProtoConstants.GroupMemberUpdateEventType.Group_Member_Event_Type_Update, (type == 0 ? ProtoConstants.GroupMemberType.GroupMemberType_Normal : ProtoConstants.GroupMemberType.GroupMemberType_Manager) + "");
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -1512,6 +1750,25 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@Override
public Set<String> getGroupManagers(String groupId, boolean includeOwner) {
Set<String> ret = new HashSet<>();
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
Collection<WFCMessage.GroupMember> members = groupMembers.get(groupId);
if (members == null || members.size() == 0) {
members = loadGroupMemberFromDB(hzInstance, groupId);
}
for (WFCMessage.GroupMember member : members) {
if(member.getType() == GroupMemberType_Manager || (member.getType() == GroupMemberType_Owner && includeOwner)) {
ret.add(member.getMemberId());
}
}
return ret;
}
@Override @Override
public ErrorCode recallMessage(long messageUid, String operatorId, String clientId, boolean isAdmin) { public ErrorCode recallMessage(long messageUid, String operatorId, String clientId, boolean isAdmin) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
@@ -1601,6 +1858,26 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
public ErrorCode recallCastMessage(long messageUid, String operatorId) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<Long, MessageBundle> mIMap = hzInstance.getMap(MESSAGES_MAP);
MessageBundle messageBundle = mIMap.get(messageUid);
if (messageBundle != null) {
WFCMessage.Message message = messageBundle.getMessage();
message = message.toBuilder().setContent(WFCMessage.MessageContent.newBuilder().setContent(operatorId).setType(80).setData(ByteString.copyFrom(String.valueOf(messageUid).getBytes()))).build();
messageBundle.setMessage(message);
messageBundle.setFromClientId(null);
databaseStore.deleteMessage(messageUid);
mIMap.set(messageUid, messageBundle, 7, TimeUnit.DAYS);
return ErrorCode.ERROR_CODE_SUCCESS;
} else {
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
}
@Override @Override
public void clearUserMessages(String userId) { public void clearUserMessages(String userId) {
mWriteLock.lock(); mWriteLock.lock();
@@ -1629,7 +1906,7 @@ public class MemoryMessagesStore implements IMessagesStore {
@Override @Override
public ErrorCode getUserInfo(List<WFCMessage.UserRequest> requestList, WFCMessage.PullUserResult.Builder builder) { public ErrorCode getUserInfo(String fromUser, List<WFCMessage.UserRequest> requestList, WFCMessage.PullUserResult.Builder builder) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS); IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
@@ -1651,6 +1928,27 @@ public class MemoryMessagesStore implements IMessagesStore {
} else { } else {
LOG.debug("Get user info, user {} userDt {} : request {}",request.getUid(), user.getUpdateDt(), request.getUpdateDt()); LOG.debug("Get user info, user {} userDt {} : request {}",request.getUid(), user.getUpdateDt(), request.getUpdateDt());
if (user.getUpdateDt() > request.getUpdateDt()) { if (user.getUpdateDt() > request.getUpdateDt()) {
if(!mUserHideProperties.isEmpty() && !user.getUid().equals(fromUser)) {
WFCMessage.User.Builder userBuilder = user.toBuilder();
for (Integer i:mUserHideProperties) {
if(i == Modify_Gender) {
userBuilder.clearGender();
} else if(i == Modify_Mobile) {
userBuilder.clearMobile();
} else if(i == Modify_Email) {
userBuilder.clearEmail();
} else if(i == Modify_Address) {
userBuilder.clearAddress();
} else if(i == Modify_Company) {
userBuilder.clearCompany();
} else if(i == Modify_Social) {
userBuilder.clearSocial();
} else if(i == Modify_Extra) {
userBuilder.clearExtra();
}
}
user = userBuilder.build();
}
resultBuilder.setUser(user); resultBuilder.setUser(user);
resultBuilder.setCode(ProtoConstants.UserResultCode.Success); resultBuilder.setCode(ProtoConstants.UserResultCode.Success);
} else { } else {
@@ -1699,10 +1997,11 @@ public class MemoryMessagesStore implements IMessagesStore {
builder.setPortrait(entry.getValue()); builder.setPortrait(entry.getValue());
modified = true; modified = true;
break; break;
case Modify_Mobile: //禁止客户端直接修改电话号码,只能通过admin api来修改
builder.setMobile(entry.getValue()); // case Modify_Mobile:
modified = true; // builder.setMobile(entry.getValue());
break; // modified = true;
// break;
case Modify_Email: case Modify_Email:
builder.setEmail(entry.getValue()); builder.setEmail(entry.getValue());
modified = true; modified = true;
@@ -1733,6 +2032,9 @@ public class MemoryMessagesStore implements IMessagesStore {
user = builder.build(); user = builder.build();
databaseStore.updateUser(user); databaseStore.updateUser(user);
mUserMap.set(userId, user); mUserMap.set(userId, user);
callbackUserInfoEvent(user);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} else { } else {
return ErrorCode.ERROR_CODE_NOT_MODIFIED; return ErrorCode.ERROR_CODE_NOT_MODIFIED;
@@ -1826,6 +2128,56 @@ public class MemoryMessagesStore implements IMessagesStore {
return out; return out;
} }
@Override
public ErrorCode updateUserInfo(InputOutputUserInfo userInfo, int flag) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
WFCMessage.User user = mUserMap.get(userInfo.getUserId());
if(user == null) {
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
WFCMessage.User.Builder builder = user.toBuilder();
if((flag & Update_User_DisplayName) > 0) {
builder.setDisplayName(userInfo.getDisplayName());
}
if((flag & Update_User_Portrait) > 0) {
builder.setPortrait(userInfo.getPortrait());
}
if((flag & Update_User_Gender) > 0) {
builder.setGender(userInfo.getGender());
}
if((flag & Update_User_Mobile) > 0) {
builder.setMobile(userInfo.getMobile());
}
if((flag & Update_User_Email) > 0) {
builder.setEmail(userInfo.getEmail());
}
if((flag & Update_User_Address) > 0) {
builder.setAddress(userInfo.getAddress());
}
if((flag & Update_User_Company) > 0) {
builder.setCompany(userInfo.getCompany());
}
if((flag & Update_User_Social) > 0) {
builder.setSocial(userInfo.getSocial());
}
if((flag & Update_User_Extra) > 0) {
builder.setExtra(userInfo.getExtra());
}
builder.setUpdateDt(System.currentTimeMillis());
user = builder.build();
try {
databaseStore.updateUser(user);
} catch (Exception e) {
e.printStackTrace();
return ErrorCode.ERROR_CODE_SERVER_ERROR;
}
mUserMap.put(user.getUid(), user);
callbackUserInfoEvent(user);
return ErrorCode.ERROR_CODE_SUCCESS;
}
@Override @Override
public void addUserInfo(WFCMessage.User user, String password) throws Exception { public void addUserInfo(WFCMessage.User user, String password) throws Exception {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
@@ -1836,6 +2188,8 @@ public class MemoryMessagesStore implements IMessagesStore {
databaseStore.updateUser(user); databaseStore.updateUser(user);
mUserMap.put(user.getUid(), user); mUserMap.put(user.getUid(), user);
databaseStore.updateUserPassword(user.getUid(), password); databaseStore.updateUserPassword(user.getUid(), password);
callbackUserInfoEvent(user);
} }
@Override @Override
@@ -1855,6 +2209,15 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
@Override
public void updateUserInfo(WFCMessage.User user) throws Exception {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
if(mUserMap.get(user.getUid()) != null) {
databaseStore.updateUser(user);
mUserMap.put(user.getUid(), user);
}
}
@Override @Override
public WFCMessage.User getUserInfo(String userId) { public WFCMessage.User getUserInfo(String userId) {
@@ -1930,6 +2293,7 @@ public class MemoryMessagesStore implements IMessagesStore {
chatroomInfo = builder.build(); chatroomInfo = builder.build();
} }
chatroomInfoMap.put(chatroomId, chatroomInfo); chatroomInfoMap.put(chatroomId, chatroomInfo);
callbackChatroomInfoUpdateEvent(chatroomId, Chatroom_Event_Create);
} }
@Override @Override
@@ -1940,6 +2304,7 @@ public class MemoryMessagesStore implements IMessagesStore {
if (room != null) { if (room != null) {
room = room.toBuilder().setUpdateDt(System.currentTimeMillis()).setState(ProtoConstants.ChatroomState.Chatroom_State_End).build(); room = room.toBuilder().setUpdateDt(System.currentTimeMillis()).setState(ProtoConstants.ChatroomState.Chatroom_State_End).build();
chatroomInfoMap.put(chatroomId, room); chatroomInfoMap.put(chatroomId, room);
callbackChatroomInfoUpdateEvent(chatroomId, Chatroom_Event_Destroy);
} }
} }
@@ -2326,6 +2691,8 @@ public class MemoryMessagesStore implements IMessagesStore {
heads[1] = friendData1.getTimestamp(); heads[1] = friendData1.getTimestamp();
friendsMap.remove(userId); friendsMap.remove(userId);
friendsMap.remove(request.getTargetUid()); friendsMap.remove(request.getTargetUid());
callbackRelationEvent(userId, request.getTargetUid(), 0, "" + request.getStatus());
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2388,6 +2755,8 @@ public class MemoryMessagesStore implements IMessagesStore {
msgBuilder.setConversation(WFCMessage.Conversation.newBuilder().setTarget(userId).setLine(0).setType(ProtoConstants.ConversationType.ConversationType_Private).build()); msgBuilder.setConversation(WFCMessage.Conversation.newBuilder().setTarget(userId).setLine(0).setType(ProtoConstants.ConversationType.ConversationType_Private).build());
msgBuilder.setContent(WFCMessage.MessageContent.newBuilder().setType(1).setSearchableContent(existRequest.getReason()).build()); msgBuilder.setContent(WFCMessage.MessageContent.newBuilder().setType(1).setSearchableContent(existRequest.getReason()).build());
callbackRelationEvent(userId, request.getTargetUid(), 0, "1");
} }
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2436,6 +2805,7 @@ public class MemoryMessagesStore implements IMessagesStore {
heads[0] = friendData.getTimestamp(); heads[0] = friendData.getTimestamp();
callbackRelationEvent(fromUser, targetUserId, 2, state+"");
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2477,7 +2847,9 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
if (friendData == null) { if (friendData == null) {
return ErrorCode.ERROR_CODE_NOT_EXIST; friendData = new FriendData();
friendData.setUserId(fromUser);
friendData.setFriendUid(targetUserId);
} }
friendData.setAlias(alias); friendData.setAlias(alias);
@@ -2489,6 +2861,7 @@ public class MemoryMessagesStore implements IMessagesStore {
friendsMap.remove(fromUser); friendsMap.remove(fromUser);
callbackRelationEvent(fromUser, targetUserId, 1, alias);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2507,6 +2880,7 @@ public class MemoryMessagesStore implements IMessagesStore {
chatroomMessages.put(userId, new TreeMap<>()); chatroomMessages.put(userId, new TreeMap<>());
mWriteLock.unlock(); mWriteLock.unlock();
callbackChatroomMemberEvent(userId, chatroomId, Arrays.asList(userId), Chatroom_Member_Event_Join);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2519,6 +2893,8 @@ public class MemoryMessagesStore implements IMessagesStore {
mWriteLock.lock(); mWriteLock.lock();
chatroomMessages.remove(userId); chatroomMessages.remove(userId);
mWriteLock.unlock(); mWriteLock.unlock();
callbackChatroomMemberEvent(userId, chatroomId, Arrays.asList(userId), Chatroom_Member_Event_Leave);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2577,6 +2953,7 @@ public class MemoryMessagesStore implements IMessagesStore {
friendsMap.remove(userId); friendsMap.remove(userId);
friendsMap.remove(friendUid); friendsMap.remove(friendUid);
callbackRelationEvent(userId, friendUid, 0, "0");
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2728,9 +3105,20 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
userSettingMap.put(userId, settingEntry); userSettingMap.put(userId, settingEntry);
userGlobalSlientMap.remove(userId);
userConvSlientMap.remove(userId); if(request.getScope() == UserSettingScope.kUserSettingConversationSilent) {
userPushHiddenDetail.remove(userId); int firstSplit = request.getKey().indexOf("-");
int type = Integer.parseInt(request.getKey().substring(0, firstSplit));
int secondSplit = request.getKey().indexOf("-", firstSplit+1);
int line = Integer.parseInt(request.getKey().substring(firstSplit+1, secondSplit));
String target = request.getKey().substring(secondSplit+1);
String key = userId + "|" + type + "|" + target + "|" + line;
userConvSlientMap.remove(key);
} else if(request.getScope() == UserSettingScope.kUserSettingGlobalSilent) {
userGlobalSlientMap.remove(userId);
} else if(request.getScope() == UserSettingScope.kUserSettingHiddenNotificationDetail) {
userPushHiddenDetail.remove(userId);
}
IMHandler.getPublisher().publishNotification(IMTopic.NotifyUserSettingTopic, userId, updateDt); IMHandler.getPublisher().publishNotification(IMTopic.NotifyUserSettingTopic, userId, updateDt);
return updateDt; return updateDt;
} }
@@ -2744,7 +3132,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
@Override @Override
public boolean getUserGlobalSlient(String userId) { public boolean getUserGlobalSilent(String userId) {
Boolean slient = userGlobalSlientMap.get(userId); Boolean slient = userGlobalSlientMap.get(userId);
if (slient == null) { if (slient == null) {
WFCMessage.UserSettingEntry entry = getUserSetting(userId, UserSettingScope.kUserSettingGlobalSilent, null); WFCMessage.UserSettingEntry entry = getUserSetting(userId, UserSettingScope.kUserSettingGlobalSilent, null);
@@ -2774,7 +3162,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
@Override @Override
public boolean getUserConversationSlient(String userId, WFCMessage.Conversation conversation) { public boolean getUserConversationSilent(String userId, WFCMessage.Conversation conversation) {
String key = userId + "|" + conversation.getType() + "|" + conversation.getTarget() + "|" + conversation.getLine(); String key = userId + "|" + conversation.getType() + "|" + conversation.getTarget() + "|" + conversation.getLine();
Boolean slient = userConvSlientMap.get(key); Boolean slient = userConvSlientMap.get(key);
if (slient == null) { if (slient == null) {
@@ -2785,7 +3173,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} else { } else {
slient = true; slient = true;
} }
userConvSlientMap.put(userId, slient); userConvSlientMap.put(key, slient);
} }
return slient; return slient;
} }
@@ -2799,6 +3187,42 @@ public class MemoryMessagesStore implements IMessagesStore {
return false; return false;
} }
} }
private Date getTodayDate() {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DATE);
calendar.set(year, month, day, 0, 0, 0);
return calendar.getTime();
}
@Override
public boolean isUserNoDisturbing(String userId) {
WFCMessage.UserSettingEntry entry = getUserSetting(userId, UserSettingScope.kUserSettingNoDisturbing, "");
if (entry != null && !StringUtil.isNullOrEmpty(entry.getValue())) {
String[] arr = entry.getValue().split("\\|");
if (arr.length == 2) {
int nowMins = (int)((System.currentTimeMillis() - getTodayDate().getTime())/1000/60);
try {
int startMins = Integer.parseInt(arr[0]);
int endMins = Integer.parseInt(arr[1]);
if (endMins > startMins) {
if (endMins > nowMins && nowMins > startMins) {
return true;
}
} else {
if (endMins > nowMins || nowMins > startMins) {
return true;
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
return false;
}
@Override @Override
public ErrorCode createChannel(String operator, WFCMessage.ChannelInfo channelInfo) { public ErrorCode createChannel(String operator, WFCMessage.ChannelInfo channelInfo) {
@@ -2807,6 +3231,7 @@ public class MemoryMessagesStore implements IMessagesStore {
mIMap.put(channelInfo.getTargetId(), channelInfo); mIMap.put(channelInfo.getTargetId(), channelInfo);
callbackChannelInfoUpdateEvent(operator, channelInfo.getTargetId(), Channel_Event_Create);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2859,6 +3284,7 @@ public class MemoryMessagesStore implements IMessagesStore {
newInfoBuilder.setUpdateDt(System.currentTimeMillis()); newInfoBuilder.setUpdateDt(System.currentTimeMillis());
mIMap.put(channelId, newInfoBuilder.build()); mIMap.put(channelId, newInfoBuilder.build());
callbackChannelInfoUpdateEvent(operator, channelId, Channel_Event_Update);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2885,6 +3311,8 @@ public class MemoryMessagesStore implements IMessagesStore {
newInfoBuilder.setOwner(newOwner); newInfoBuilder.setOwner(newOwner);
newInfoBuilder.setUpdateDt(System.currentTimeMillis()); newInfoBuilder.setUpdateDt(System.currentTimeMillis());
mIMap.put(channelId, newInfoBuilder.build()); mIMap.put(channelId, newInfoBuilder.build());
callbackChannelInfoUpdateEvent(operator, channelId, Channel_Event_Transfer);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2909,6 +3337,8 @@ public class MemoryMessagesStore implements IMessagesStore {
newInfoBuilder.setStatus(oldInfo.getStatus() | Channel_State_Mask_Deleted); newInfoBuilder.setStatus(oldInfo.getStatus() | Channel_State_Mask_Deleted);
newInfoBuilder.setUpdateDt(System.currentTimeMillis()); newInfoBuilder.setUpdateDt(System.currentTimeMillis());
mIMap.put(channelId, newInfoBuilder.build()); mIMap.put(channelId, newInfoBuilder.build());
callbackChannelInfoUpdateEvent(operator, channelId, Channel_Event_Destroy);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -3023,6 +3453,22 @@ public class MemoryMessagesStore implements IMessagesStore {
return null; return null;
} }
@Override
public boolean isAllowClientCustomGroupNotification() {
return mGroupAllowClientCustomOperationNotification;
}
@Override
public int getVisibleQuitKickoffNotification() {
return mGroupVisibleQuitKickoffNotification;
}
@Override
public List<Integer> getClientForbiddenSendTypes() {
return mForbiddenClientSendTypes;
}
@Override @Override
public long getMessageHead(String user) { public long getMessageHead(String user) {
TreeMap<Long, Long> maps = userMessages.get(user); TreeMap<Long, Long> maps = userMessages.get(user);
@@ -57,6 +57,8 @@ public class MemorySessionStore implements ISessionsStore {
private int deleted; private int deleted;
private boolean pullHistoryMsg;
public int getDeleted() { public int getDeleted() {
return deleted; return deleted;
} }
@@ -139,6 +141,14 @@ public class MemorySessionStore implements ISessionsStore {
this.carrierName = carrierName; this.carrierName = carrierName;
} }
public boolean isPullHistoryMsg() {
return pullHistoryMsg;
}
public void setPullHistoryMsg(boolean pullHistoryMsg) {
this.pullHistoryMsg = pullHistoryMsg;
}
public long getUpdateDt() { public long getUpdateDt() {
return updateDt; return updateDt;
} }
@@ -339,18 +349,22 @@ public class MemorySessionStore implements ISessionsStore {
Session session = sessions.get(clientID); Session session = sessions.get(clientID);
if (session != null && !session.username.equals(username)) { if (session != null && !session.username.equals(username)) {
if (userSessions.get(username) != null) { if (userSessions.get(session.username) != null) {
userSessions.get(username).remove(clientID); userSessions.get(session.username).remove(clientID);
} }
session = null;
} }
ClientSession clientSession = new ClientSession(clientID, this); ClientSession clientSession = new ClientSession(clientID, this);
session = databaseStore.getSession(username, clientID, clientSession); if(session == null) {
session = databaseStore.getSession(username, clientID, clientSession);
if (session == null) { if (session == null) {
session = databaseStore.createSession(username, clientID, clientSession, platform); 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) { if (session.getDeleted() > 0) {
session.setDeleted(0); session.setDeleted(0);
@@ -393,8 +407,8 @@ public class MemorySessionStore implements ISessionsStore {
if (remove) { if (remove) {
sessions.remove(c); sessions.remove(c);
mServer.getProcessor().kickoffSession(s);
it.remove(); it.remove();
mServer.getProcessor().kickoffSession(s);
} }
} }
} }
@@ -405,6 +419,34 @@ public class MemorySessionStore implements ISessionsStore {
return session; 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 @Override
public ErrorCode loadActiveSession(String username, String clientID) { public ErrorCode loadActiveSession(String username, String clientID) {
@@ -452,7 +494,6 @@ public class MemorySessionStore implements ISessionsStore {
session.setUsername(username); session.setUsername(username);
sessions.put(clientID, session); sessions.put(clientID, session);
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username); ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
sessionSet.add(clientID); sessionSet.add(clientID);
@@ -491,11 +532,15 @@ public class MemorySessionStore implements ISessionsStore {
@Override @Override
public void loadUserSession(String username, String clientID) { public void loadUserSession(String username, String clientID) {
if (sessions.containsKey(clientID)) { if (sessions.containsKey(clientID)) {
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
sessionSet.add(clientID);
return; return;
} }
Session session = databaseStore.getSession(username, clientID, new ClientSession(clientID, this)); Session session = databaseStore.getSession(username, clientID, new ClientSession(clientID, this));
if (session != null) { if (session != null) {
sessions.put(clientID, session); sessions.put(clientID, session);
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
sessionSet.add(clientID);
} }
} }
@@ -94,6 +94,7 @@ public class Server {
private ThreadPoolExecutorWrapper dbScheduler; private ThreadPoolExecutorWrapper dbScheduler;
private ThreadPoolExecutorWrapper imBusinessScheduler; private ThreadPoolExecutorWrapper imBusinessScheduler;
private ThreadPoolExecutorWrapper callbackScheduler;
private IConfig mConfig; private IConfig mConfig;
@@ -225,7 +226,7 @@ public class Server {
handlers = Collections.emptyList(); handlers = Collections.emptyList();
} }
DBUtil.init(config); 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(","); String[] strs = strKey.split(",");
if(strs.length != 16) { if(strs.length != 16) {
LOG.error("Key error, it length should be 16"); LOG.error("Key error, it length should be 16");
@@ -243,6 +244,7 @@ public class Server {
int threadNum = Runtime.getRuntime().availableProcessors() * 2; int threadNum = Runtime.getRuntime().availableProcessors() * 2;
dbScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(threadNum), threadNum, "db"); dbScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(threadNum), threadNum, "db");
imBusinessScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(threadNum), threadNum, "business"); 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); final String handlerProp = System.getProperty(BrokerConstants.INTERCEPT_HANDLER_PROPERTY_NAME);
if (handlerProp != null) { if (handlerProp != null) {
@@ -251,6 +253,9 @@ public class Server {
initMediaServerConfig(config); initMediaServerConfig(config);
String monitorEventAddress = config.getProperty(MONITOR_Exception_Event_Address);
Utility.setMonitorEventAddress(monitorEventAddress);
final String persistencePath = config.getProperty(BrokerConstants.PERSISTENT_STORE_PROPERTY_NAME); final String persistencePath = config.getProperty(BrokerConstants.PERSISTENT_STORE_PROPERTY_NAME);
LOG.info("Configuring Using persistent store file, path={}", persistencePath); LOG.info("Configuring Using persistent store file, path={}", persistencePath);
m_store = initStore(config, this); 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!"); System.out.println("Server will flush data to db before shutting down, please wait 5 seconds!");
LOG.info("Unbinding server from the configured ports"); LOG.info("Unbinding server from the configured ports");
m_shutdowning = true; m_shutdowning = true;
DBUtil.SystemExiting = true;
m_acceptor.close(); m_acceptor.close();
LOG.trace("Stopping MQTT protocol processor"); LOG.trace("Stopping MQTT protocol processor");
@@ -447,6 +453,7 @@ public class Server {
dbScheduler.shutdown(); dbScheduler.shutdown();
imBusinessScheduler.shutdown(); imBusinessScheduler.shutdown();
callbackScheduler.shutdown();
LOG.info("Moquette server has been stopped."); LOG.info("Moquette server has been stopped.");
} }
@@ -507,4 +514,8 @@ public class Server {
public ThreadPoolExecutorWrapper getImBusinessScheduler() { public ThreadPoolExecutorWrapper getImBusinessScheduler() {
return imBusinessScheduler; return imBusinessScheduler;
} }
public ThreadPoolExecutorWrapper getCallbackScheduler() {
return callbackScheduler;
}
} }
@@ -35,10 +35,6 @@ public abstract class IConfig {
void assignDefaults() { void assignDefaults() {
setProperty(BrokerConstants.PORT_PROPERTY_NAME, Integer.toString(BrokerConstants.PORT)); setProperty(BrokerConstants.PORT_PROPERTY_NAME, Integer.toString(BrokerConstants.PORT));
setProperty(BrokerConstants.HOST_PROPERTY_NAME, BrokerConstants.HOST); 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, ""); 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 @Override
public void setProperty(String name, String value) { public void setProperty(String name, String value) {
m_properties.setProperty(name, value); m_properties.setProperty(name, value);
@@ -49,6 +49,7 @@ import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import java.io.IOException; import java.io.IOException;
import java.net.BindException;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -57,35 +58,6 @@ import static io.netty.channel.ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE;
public class NettyAcceptor implements ServerAcceptor { 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 class PipelineInitializer {
abstract void init(ChannelPipeline pipeline) throws Exception; abstract void init(ChannelPipeline pipeline) throws Exception;
@@ -144,17 +116,6 @@ public class NettyAcceptor implements ServerAcceptor {
this.errorsCather = Optional.empty(); this.errorsCather = Optional.empty();
initializePlainTCPTransport(mqttHandler, props); 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) { 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); f.sync().addListener(FIRE_EXCEPTION_ON_FAILURE);
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
LOG.error("An interruptedException was caught while initializing server. Protocol={}", protocol, 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() { public void close() {
LOG.info("Closing Netty acceptor..."); LOG.info("Closing Netty acceptor...");
if (m_workerGroup == null || m_bossGroup == null) { if (m_workerGroup == null || m_bossGroup == null) {
@@ -16,6 +16,7 @@
package io.moquette.spi; package io.moquette.spi;
import cn.wildfirechat.pojos.InputOutputUserInfo;
import cn.wildfirechat.pojos.SystemSettingPojo; import cn.wildfirechat.pojos.SystemSettingPojo;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.xiaoleilu.loServer.model.FriendData; import com.xiaoleilu.loServer.model.FriendData;
@@ -30,6 +31,7 @@ import io.netty.handler.codec.mqtt.MqttQoS;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -99,7 +101,7 @@ public interface IMessagesStore {
DatabaseStore getDatabaseStore(); DatabaseStore getDatabaseStore();
WFCMessage.Message storeMessage(String fromUser, String fromClientId, WFCMessage.Message message); WFCMessage.Message storeMessage(String fromUser, String fromClientId, WFCMessage.Message message);
void storeSensitiveMessage(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(); Set<String> getAllEnds();
WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType); WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType);
WFCMessage.PullMessageResult loadRemoteMessages(String user, WFCMessage.Conversation conversation, long beforeUid, int count); WFCMessage.PullMessageResult loadRemoteMessages(String user, WFCMessage.Conversation conversation, long beforeUid, int count);
@@ -121,14 +123,18 @@ public interface IMessagesStore {
ErrorCode setGroupManager(String operator, String groupId, int type, List<String> userList, boolean isAdmin); ErrorCode setGroupManager(String operator, String groupId, int type, List<String> userList, boolean isAdmin);
boolean isMemberInGroup(String member, String groupId); boolean isMemberInGroup(String member, String groupId);
ErrorCode canSendMessageInGroup(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 recallMessage(long messageUid, String operatorId, String clientId, boolean isAdmin);
ErrorCode recallCastMessage(long messageUid, String operatorId);
void clearUserMessages(String userId); void clearUserMessages(String userId);
WFCMessage.Robot getRobot(String robotId); WFCMessage.Robot getRobot(String robotId);
void addRobot(WFCMessage.Robot robot); 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; ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request) throws Exception;
void updateUserOnlineSetting(MemorySessionStore.Session session, boolean online); void updateUserOnlineSetting(MemorySessionStore.Session session, boolean online);
@@ -137,8 +143,10 @@ public interface IMessagesStore {
int getUserStatus(String userId); int getUserStatus(String userId);
List<InputOutputUserBlockStatus> getUserStatusList(); List<InputOutputUserBlockStatus> getUserStatusList();
ErrorCode updateUserInfo(InputOutputUserInfo userInfo, int flag);
void addUserInfo(WFCMessage.User user, String password) throws Exception; void addUserInfo(WFCMessage.User user, String password) throws Exception;
void destoryUser(String userId); void destoryUser(String userId);
void updateUserInfo(WFCMessage.User user) throws Exception;
WFCMessage.User getUserInfo(String userId); WFCMessage.User getUserInfo(String userId);
WFCMessage.User getUserInfoByName(String name); WFCMessage.User getUserInfoByName(String name);
WFCMessage.User getUserInfoByMobile(String mobile); WFCMessage.User getUserInfoByMobile(String mobile);
@@ -184,12 +192,12 @@ public interface IMessagesStore {
List<WFCMessage.UserSettingEntry> getUserSetting(String userId, int scope); List<WFCMessage.UserSettingEntry> getUserSetting(String userId, int scope);
long updateUserSettings(String userId, WFCMessage.ModifyUserSettingReq request); long updateUserSettings(String userId, WFCMessage.ModifyUserSettingReq request);
void clearUserSettings(String userId); void clearUserSettings(String userId);
boolean getUserGlobalSilent(String userId);
boolean getUserGlobalSlient(String userId);
boolean getUserPushHiddenDetail(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 getSilentWhenPcOnline(String userId);
boolean isUserNoDisturbing(String userId);
ErrorCode createChannel(String operator, WFCMessage.ChannelInfo channelInfo); ErrorCode createChannel(String operator, WFCMessage.ChannelInfo channelInfo);
void clearUserChannels(String userId); void clearUserChannels(String userId);
ErrorCode modifyChannelInfo(String operator, String channelId, int modifyType, String value); ErrorCode modifyChannelInfo(String operator, String channelId, int modifyType, String value);
@@ -207,6 +215,12 @@ public interface IMessagesStore {
List<String> getAllSensitiveWords(); List<String> getAllSensitiveWords();
WFCMessage.Message getMessage(long messageId); WFCMessage.Message getMessage(long messageId);
boolean isAllowClientCustomGroupNotification();
int getVisibleQuitKickoffNotification();
List<Integer> getClientForbiddenSendTypes();
long getMessageHead(String user); long getMessageHead(String user);
long getFriendHead(String user); long getFriendHead(String user);
long getFriendRqHead(String user); long getFriendRqHead(String user);
@@ -51,6 +51,8 @@ public interface ISessionsStore {
void updateSessionToken(Session session, boolean voip); void updateSessionToken(Session session, boolean voip);
void clearUserSession(String username); void clearUserSession(String username);
void kickoffUserClient(String userId, String clientId);
/** /**
* @param clientID * @param clientID
* the client owning the session. * the client owning the session.
@@ -29,6 +29,7 @@ import com.xiaoleilu.loServer.model.FriendData;
import io.moquette.persistence.*; import io.moquette.persistence.*;
import io.moquette.persistence.MemorySessionStore.Session; import io.moquette.persistence.MemorySessionStore.Session;
import io.moquette.server.ConnectionDescriptorStore; import io.moquette.server.ConnectionDescriptorStore;
import io.moquette.server.Server;
import io.moquette.spi.IMessagesStore; import io.moquette.spi.IMessagesStore;
import io.moquette.spi.ISessionsStore; import io.moquette.spi.ISessionsStore;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@@ -48,6 +49,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent; import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
public class MessagesPublisher { public class MessagesPublisher {
@@ -160,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) { 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) { if (persistFlag == Transparent) {
publishTransparentMessage2Receivers(messageHead, receivers, pullType); publishTransparentMessage2Receivers(messageHead, receivers, pullType, exceptClientId);
return; return;
} }
@@ -175,7 +177,14 @@ public class MessagesPublisher {
message = m_messagesStore.getMessage(messageHead); message = m_messagesStore.getMessage(messageHead);
} }
final WFCMessage.Message finalMsg = message; 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; continue;
} }
} }
@@ -243,11 +252,13 @@ public class MessagesPublisher {
} }
} }
boolean isSlient; boolean isSilent;
boolean isConvSilent = false;
if (pullType == ProtoConstants.PullType.Pull_ChatRoom) { if (pullType == ProtoConstants.PullType.Pull_ChatRoom) {
isSlient = true; isSilent = true;
isConvSilent = true;
} else { } else {
isSlient = false; isSilent = false;
if (!user.equals(sender)) { if (!user.equals(sender)) {
WFCMessage.Conversation conversation; WFCMessage.Conversation conversation;
@@ -257,34 +268,32 @@ public class MessagesPublisher {
conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(target).build(); conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(target).build();
} }
if (m_messagesStore.getUserConversationSilent(user, conversation)) {
if (m_messagesStore.getUserConversationSlient(user, conversation)) {
LOG.info("The conversation {}-{}-{} is slient", conversation.getType(), conversation.getTarget(), conversation.getLine()); 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); LOG.info("The user {} is global sliented", user);
isSlient = true; isSilent = true;
} }
if (isPcOnline && m_messagesStore.getSilentWhenPcOnline(user)) { if (!isSilent && isPcOnline && m_messagesStore.getSilentWhenPcOnline(user)) {
LOG.info("The user {} pc online and silent when pc online", user); LOG.info("The user {} pc online and silent when pc online", user);
isSlient = true; 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 (!StringUtil.isNullOrEmpty(pushContent) || messageContentType == 400) {
if (!isSlient && (persistFlag & 0x02) > 0) { if (!isConvSilent && (persistFlag & 0x02) > 0) {
targetSession.setUnReceivedMsgs(targetSession.getUnReceivedMsgs() + 1); targetSession.setUnReceivedMsgs(targetSession.getUnReceivedMsgs() + 1);
} }
} }
if (isSlient) {
if (mentionType == 2 || (mentionType == 1 && mentionTargets.contains(user))) {
isSlient = false;
}
}
} }
boolean needPush = !user.equals(sender); boolean needPush = !user.equals(sender);
@@ -315,15 +324,15 @@ public class MessagesPublisher {
int curMentionType = 0; int curMentionType = 0;
if (mentionType == 2) { if (mentionType == 2) {
curMentionType = 2; curMentionType = 2;
isSlient = false; isConvSilent = false;
} else if (mentionType == 1){ } else if (mentionType == 1){
if (mentionTargets != null && mentionTargets.contains(user)) { if (mentionTargets != null && mentionTargets.contains(user)) {
curMentionType = 1; 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); LOG.info("push content is empty and contenttype is {}", messageContentType);
continue; continue;
} }
@@ -333,8 +342,13 @@ public class MessagesPublisher {
continue; continue;
} }
if (isSlient) { if (isConvSilent) {
LOG.info("Slient of user or conversation"); LOG.info("Silent of user or conversation");
continue;
}
if (isSilent) {
LOG.info("Silent of user");
continue; continue;
} }
@@ -359,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); WFCMessage.Message message = m_messagesStore.getMessage(messageHead);
if (message != null) { if (message != null) {
@@ -375,6 +408,9 @@ public class MessagesPublisher {
if (targetSession.getClientID() == null) { if (targetSession.getClientID() == null) {
continue; continue;
} }
if (targetSession.getClientID().equals(exceptClientId)) {
continue;
}
boolean targetIsActive = this.connectionDescriptors.isConnected(targetSession.getClientSession().clientID); boolean targetIsActive = this.connectionDescriptors.isConnected(targetSession.getClientSession().clientID);
if (targetIsActive) { if (targetIsActive) {
@@ -531,7 +567,14 @@ public class MessagesPublisher {
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) { if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget()); WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback())) { 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(); long messageId = message.getMessageId();
@@ -571,13 +614,51 @@ public class MessagesPublisher {
} }
public void forwardMessage(final WFCMessage.Message message, String forwardUrl) { 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 forwardMessageWithCallback(final WFCMessage.Message message, String forwardUrl, HttpUtils.HttpCallback callback) {
try {
HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), new HttpUtils.HttpCallback() {
@Override
public void onSuccess(String content) {
Server.getServer().getImBusinessScheduler().execute(()->{
callback.onSuccess(content);
});
}
@Override
public void onFailure(int statusCode, String errorMessage) {
Server.getServer().getImBusinessScheduler().execute(()->{
callback.onFailure(statusCode, errorMessage);
});
}
});
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
} }
public void notifyChannelListenStatusChanged(WFCMessage.ChannelInfo channelInfo, String user, boolean listen) { public void notifyChannelListenStatusChanged(WFCMessage.ChannelInfo channelInfo, String user, boolean listen) {
if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback())) { if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
return; 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) { boolean sendPublish(ClientSession clientsession, MqttPublishMessage pubMessage) {
String clientId = clientsession.clientID; String clientId = clientsession.clientID;
return sendPublish(clientId, pubMessage);
}
boolean sendPublish(String clientId, MqttPublishMessage pubMessage) {
final int messageId = pubMessage.variableHeader().packetId(); final int messageId = pubMessage.variableHeader().packetId();
final String topicName = pubMessage.variableHeader().topicName(); final String topicName = pubMessage.variableHeader().topicName();
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
@@ -17,7 +17,6 @@
package io.moquette.spi.impl; package io.moquette.spi.impl;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.SendMessageData;
import cn.wildfirechat.pojos.UserOnlineStatus; import cn.wildfirechat.pojos.UserOnlineStatus;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
@@ -54,6 +53,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static io.moquette.spi.impl.InternalRepublisher.createPublishForQos; 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.moquette.spi.impl.Utils.readBytesAndRewind;
import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.*; import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.*;
import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from; import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from;
@@ -72,15 +72,30 @@ public class ProtocolProcessor {
public void kickoffSession(final MemorySessionStore.Session session) { public void kickoffSession(final MemorySessionStore.Session session) {
mServer.getImBusinessScheduler().execute(()->{ mServer.getImBusinessScheduler().execute(()->{
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID()); new Thread(() -> {
try { messagesPublisher.sendOfflineNotify(session.getClientID());
if (descriptor != null) { try {
processDisconnect(descriptor.getChannel(), true, false); Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} }
} catch (InterruptedException e) {
e.printStackTrace(); mServer.getImBusinessScheduler().execute(()->{
Utility.printExecption(LOG, e); 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();
}); });
} }
@@ -173,8 +188,7 @@ public class ProtocolProcessor {
String clientId = payload.clientIdentifier(); String clientId = payload.clientIdentifier();
LOG.info("Processing CONNECT message. CId={}, username={}", clientId, payload.userName()); LOG.info("Processing CONNECT message. CId={}, username={}", clientId, payload.userName());
if (msg.variableHeader().version() < MqttVersion.MQTT_3_1_1.protocolLevel() || if (msg.variableHeader().version() < MqttVersion.MQTT_3_1_1.protocolLevel()) {
msg.variableHeader().version() >= MqttVersion.Wildfire_Max.protocolLevel()) {
MqttConnAckMessage badProto = connAck(CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION); MqttConnAckMessage badProto = connAck(CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION);
LOG.error("MQTT protocol version is not valid. CId={}", clientId); LOG.error("MQTT protocol version is not valid. CId={}", clientId);
@@ -252,7 +266,14 @@ public class ProtocolProcessor {
public void forwardOnlineStatusEvent(String userId, String clientId, int platform, int status, String packageName) { public void forwardOnlineStatusEvent(String userId, String clientId, int platform, int status, String packageName) {
if (!StringUtil.isNullOrEmpty(mUserOnlineStatusCallback)) { 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; package io.moquette.spi.impl;
import static cn.wildfirechat.common.ErrorCode.*;
import static io.moquette.spi.impl.Utils.readBytesAndRewind; import static io.moquette.spi.impl.Utils.readBytesAndRewind;
import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from; import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from;
import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE; 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.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@@ -256,6 +254,13 @@ public class Qos1PublishHandler extends QosPublishHandler {
String imtopic = topic.getTopic(); String imtopic = topic.getTopic();
ByteBuf payload = msg.payload(); ByteBuf payload = msg.payload();
byte[] payloadContent = readBytesAndRewind(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); MemorySessionStore.Session session = m_sessionStore.getSession(clientID);
payloadContent = AES.AESDecrypt(payloadContent, session.getSecret(), true); payloadContent = AES.AESDecrypt(payloadContent, session.getSecret(), true);
imHandler(clientID, username, imtopic, payloadContent, (errorCode, ackPayload) -> sendPubAck(clientID, messageID, ackPayload, errorCode), false); imHandler(clientID, username, imtopic, payloadContent, (errorCode, ackPayload) -> sendPubAck(clientID, messageID, ackPayload, errorCode), false);
@@ -27,7 +27,7 @@ public enum MqttVersion {
MQTT_3_1_1("MQTT", (byte) 4), MQTT_3_1_1("MQTT", (byte) 4),
Wildfire_1("MQTT", (byte) 5), Wildfire_1("MQTT", (byte) 5),
Wildfire_2("MQTT", (byte) 6), Wildfire_2("MQTT", (byte) 6),
Wildfire_Max("MQTT", (byte) 7); Wildfire_Future("MQTT", (byte) 7);
private final String name; private final String name;
private final byte level; private final byte level;
@@ -59,6 +59,9 @@ public enum MqttVersion {
} }
} }
} }
if(protocolLevel > Wildfire_Future.level) {
return Wildfire_Future;
}
throw new MqttUnacceptableProtocolVersionException(protocolName + "is unknown protocol name"); throw new MqttUnacceptableProtocolVersionException(protocolName + "is unknown protocol name");
} }
@@ -68,6 +71,9 @@ public enum MqttVersion {
return mv; return mv;
} }
} }
if(protocolLevel > Wildfire_Future.level) {
return Wildfire_Future;
}
throw new MqttUnacceptableProtocolVersionException(protocolLevel + "is unknown protocol level"); throw new MqttUnacceptableProtocolVersionException(protocolLevel + "is unknown protocol level");
} }
} }
+255 -143
View File
@@ -14,6 +14,8 @@ import java.io.BufferedReader;
import java.io.FileReader; import java.io.FileReader;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List; import java.util.List;
import com.hazelcast.util.StringUtil; import com.hazelcast.util.StringUtil;
@@ -27,6 +29,8 @@ import org.slf4j.LoggerFactory;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
public class DBUtil { public class DBUtil {
private static final Logger LOG = LoggerFactory.getLogger(DBUtil.class); private static final Logger LOG = LoggerFactory.getLogger(DBUtil.class);
private static ComboPooledDataSource comboPooledDataSource = null; 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) { public static void init(IConfig config) {
String embedDB = config.getProperty(BrokerConstants.EMBED_DB_PROPERTY_NAME); String embedDB = config.getProperty(BrokerConstants.EMBED_DB_PROPERTY_NAME);
if (embedDB != null && embedDB.equals("1")) { boolean autoCleanMsgs = "true".equals(config.getProperty(BrokerConstants.DB_AUTO_CLEAN_HISTORY_MESSAGES));
IsEmbedDB = true; if (embedDB != null && embedDB.equals("1")) {
LOG.info("Use h2 database"); 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 { } else {
IsEmbedDB = false; migrateLocation = "filesystem:./migrate/mysql";
LOG.info("Use mysql database"); 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; statement.executeUpdate("CREATE DATABASE IF NOT EXISTS `" + datasourceName + "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
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.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() { String msgTableName = MessageShardingUtil.getMessageTable(MessageShardingUtil.getMsgIdFromTimestamp(System.currentTimeMillis()));
List<String> out = new ArrayList<>(); clearOneTable(msgTableName);
try{ }
BufferedReader br = new BufferedReader(new FileReader("h2/create_table.sql"));//构造一个BufferedReader类来读取文件
String s = null; private static void clearOneTable(String tableName) {
StringBuilder result = new StringBuilder(); Connection connection = null;
while((s = br.readLine())!=null) { PreparedStatement statement = null;
result.append(s); ResultSet rs = null;
if (s.contains(";")) { long mid = getMaxMidNeedClean();
out.add(result.toString());
result = new StringBuilder(); try {
} connection = DBUtil.getConnection();
} String sql = "delete from " + tableName + " where _mid <= " + mid;
br.close(); statement = connection.prepareStatement(sql);
}catch(Exception e){ int count = statement.executeUpdate();
e.printStackTrace(); LOG.info("Delete history message {} rows", count);
Utility.printExecption(LOG, e); } catch (Exception e) {
} e.printStackTrace();
return out; 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) { private static List<String> getCreateSql() {
LOG.error("error here!!!! DB connection not close correctly"); List<String> out = new ArrayList<>();
} try{
map.put(threadId, Thread.currentThread().getStackTrace().toString()); BufferedReader br = new BufferedReader(new FileReader("h2/create_table.sql"));//构造一个BufferedReader类来读取文件
Connection connection = transactionConnection.get(); String s = null;
if (connection != null) { StringBuilder result = new StringBuilder();
LOG.debug("Thread {} get db connection {}", threadId, connection); while((s = br.readLine())!=null) {
return connection; 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); LOG.debug("Thread {} get db connection {}", threadId, connection);
return connection; return connection;
} }
public static void beginTransaction() { connection = comboPooledDataSource.getConnection();
try { LOG.debug("Thread {} get db connection {}", threadId, connection);
Connection connection = getConnection(); return connection;
connection.setAutoCommit(false); }
transactionConnection.set(connection);
} catch (SQLException e) { public static void beginTransaction() {
e.printStackTrace(); try {
Utility.printExecption(LOG, e); Connection connection = getConnection();
} connection.setAutoCommit(false);
transactionConnection.set(connection);
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
} }
}
public static void commit() { public static void commit() {
try { try {
@@ -180,57 +292,57 @@ public class DBUtil {
} }
} }
//释放资源,将数据库连接还给数据库连接池 //释放资源,将数据库连接还给数据库连接池
public static void closeDB(Connection conn,PreparedStatement ps,ResultSet rs) { public static void closeDB(Connection conn,PreparedStatement ps,ResultSet rs) {
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn); LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
try { try {
if (rs!=null) { if (rs!=null) {
rs.close(); 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);
} }
} 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 { try {
if (conn!=null && transactionConnection.get() != conn) { if (ps!=null) {
conn.close(); ps.close();
map.remove(Thread.currentThread().getId());
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
} }
} 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);
}
}
} }
@@ -30,9 +30,19 @@ public class HttpUtils {
private static final Logger LOG = LoggerFactory.getLogger(HttpUtils.class); private static final Logger LOG = LoggerFactory.getLogger(HttpUtils.class);
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
static private OkHttpClient client = new OkHttpClient(); static private OkHttpClient client = new OkHttpClient();
public interface HttpCallback {
void onSuccess(String content);
void onFailure(int statusCode, String errorMessage);
}
public static void httpJsonPost(final String url, final String jsonStr){ public static void httpJsonPost(final String url, final String jsonStr) {
LOG.info("POST to {} with data {}", url, jsonStr); httpJsonPost(url, jsonStr, null);
}
public static void httpJsonPost(final String url, final String jsonStr, final HttpCallback httpCallback) {
//消息推送内容为 {"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)) { if (StringUtil.isNullOrEmpty(url)) {
LOG.error("http post failure with empty url"); LOG.error("http post failure with empty url");
return; return;
@@ -48,12 +58,27 @@ public class HttpUtils {
public void onFailure(Call call, IOException e) { public void onFailure(Call call, IOException e) {
e.printStackTrace(); e.printStackTrace();
LOG.info("POST to {} with data {} failure", url, jsonStr); LOG.info("POST to {} with data {} failure", url, jsonStr);
if(httpCallback != null) {
httpCallback.onFailure(-1, e.getMessage());
}
} }
@Override @Override
public void onResponse(Call call, Response response) throws IOException { public void onResponse(Call call, Response response) throws IOException {
LOG.info("POST to {} success with response: {}", url, response.body()); LOG.info("POST to {} success with response: {}", url, response.body());
try { try {
if(httpCallback != null) {
int code = response.code();
if(code == 200) {
if(response.body() != null && response.body().contentLength() > 0) {
httpCallback.onSuccess(response.body().string());
} else {
httpCallback.onSuccess(null);
}
} else {
httpCallback.onFailure(code, response.message());
}
}
if (response.body() != null) { if (response.body() != null) {
response.body().close(); response.body().close();
} }
@@ -12,9 +12,12 @@ public interface IMTopic {
String SendMessageTopic = "MS"; String SendMessageTopic = "MS";
String MultiCastMessageTopic = "MMC"; String MultiCastMessageTopic = "MMC";
String RecallMessageTopic = "MR"; String RecallMessageTopic = "MR";
String RecallMultiCastMessageTopic = "MRMC";
String PullMessageTopic = "MP"; String PullMessageTopic = "MP";
String NotifyMessageTopic = "MN"; String NotifyMessageTopic = "MN";
String NotifyRecallMessageTopic = "RMN"; String NotifyRecallMessageTopic = "RMN";
String NotifyOffline = "ROFL";
String BroadcastMessageTopic = "MBC"; String BroadcastMessageTopic = "MBC";
String GetUserSettingTopic = "UG"; String GetUserSettingTopic = "UG";
@@ -10,6 +10,7 @@ package win.liyufan.im;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
public class MessageShardingUtil { public class MessageShardingUtil {
private static SpinLock mLock = new SpinLock(); private static SpinLock mLock = new SpinLock();
@@ -36,9 +37,8 @@ public class MessageShardingUtil {
*/ */
public static long generateId() throws Exception { public static long generateId() throws Exception {
mLock.lock(); mLock.lock();
rotateId = (rotateId + 1)&rotateIdMask;
mLock.unLock();
rotateId = (rotateId + 1)&rotateIdMask;
long id = System.currentTimeMillis() - T201801010000; long id = System.currentTimeMillis() - T201801010000;
if (id > timeId) { if (id > timeId) {
@@ -75,6 +75,10 @@ public class MessageShardingUtil {
id <<= rotateIdWidth; id <<= rotateIdWidth;
id += rotateId; id += rotateId;
mLock.unLock();
return id; return id;
} }
@@ -84,7 +88,7 @@ public class MessageShardingUtil {
} }
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
if (mid != Long.MAX_VALUE) { if (mid != Long.MAX_VALUE && mid != 0) {
mid >>= (nodeIdWidth + rotateIdWidth); mid >>= (nodeIdWidth + rotateIdWidth);
Date date = new Date(mid + T201801010000); Date date = new Date(mid + T201801010000);
calendar.setTime(date); calendar.setTime(date);
@@ -97,8 +101,32 @@ public class MessageShardingUtil {
year %= 3; year %= 3;
return "t_messages_" + (year * 12 + month); 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) { public static String getPreviousMessageTable(long mid) {
return getMessageTable(mid, -1);
}
public static String getMessageTable(long mid, int offset) {
if (DBUtil.IsEmbedDB) { if (DBUtil.IsEmbedDB) {
return null; return null;
} }
@@ -110,11 +138,40 @@ public class MessageShardingUtil {
int month = calendar.get(Calendar.MONTH); int month = calendar.get(Calendar.MONTH);
int year = calendar.get(Calendar.YEAR); int year = calendar.get(Calendar.YEAR);
year %= 3; year %= 3;
month = month - 1;
if (month == -1) { month = month + offset;
month = 11; while (month < 0) {
month += 12;
year = (year + 3 - 1)%3; year = (year + 3 - 1)%3;
} }
while (month >= 12) {
month -= 12;
year = (year + 1)%3;
}
return "t_messages_" + (year * 12 + month); 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,16 +3,11 @@ package win.liyufan.im;
public interface UserSettingScope { public interface UserSettingScope {
int kUserSettingConversationSilent = 1; int kUserSettingConversationSilent = 1;
int kUserSettingGlobalSilent = 2; int kUserSettingGlobalSilent = 2;
int kUserSettingConversationTop = 3;
int kUserSettingHiddenNotificationDetail = 4; int kUserSettingHiddenNotificationDetail = 4;
int kUserSettinGroupHideNickname = 5;
int kUserSettingFavouriteGroup = 6;
int kUserSettingConversationSync = 7; int kUserSettingConversationSync = 7;
int kUserSettingMyChannels = 8; int kUserSettingMyChannels = 8;
int kUserSettingListenedChannels = 9; int kUserSettingListenedChannels = 9;
int kUserSettingPCOnline = 10; int kUserSettingPCOnline = 10;
int kUserSettingMuteWhenPCOnline = 15; int kUserSettingMuteWhenPCOnline = 15;
int kUserSettingNoDisturbing = 17;
int kUserSettingCustomBegin = 1000;
} }
@@ -8,12 +8,35 @@
package win.liyufan.im; 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 org.slf4j.Logger;
import java.net.*; import java.net.*;
import java.util.Enumeration; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
public class Utility { 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(){ public static InetAddress getLocalAddress(){
try { try {
Enumeration<NetworkInterface> b = NetworkInterface.getNetworkInterfaces(); Enumeration<NetworkInterface> b = NetworkInterface.getNetworkInterfaces();
@@ -29,6 +52,10 @@ public class Utility {
} }
public static void printExecption(Logger LOG, Exception e) { public static void printExecption(Logger LOG, Exception e) {
printExecption(LOG, e, 0);
}
public static void printExecption(Logger LOG, Exception e, int eventType) {
String message = ""; String message = "";
for(StackTraceElement stackTraceElement : e.getStackTrace()) { for(StackTraceElement stackTraceElement : e.getStackTrace()) {
@@ -36,6 +63,58 @@ public class Utility {
} }
LOG.error("Exception: {}", e.getMessage()); LOG.error("Exception: {}", e.getMessage());
LOG.error(message); 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, public static String getMacAddress() throws UnknownHostException,
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId> <groupId>cn.wildfirechat</groupId>
<version>0.46</version> <version>0.55</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -17,6 +17,7 @@ public interface APIPath {
String Sensitive_Query = "/admin/sensitive/query"; String Sensitive_Query = "/admin/sensitive/query";
String Create_User = "/admin/user/create"; String Create_User = "/admin/user/create";
String Update_User = "/admin/user/update";
String Destroy_User = "/admin/user/destroy"; String Destroy_User = "/admin/user/destroy";
String Create_Robot = "/admin/robot/create"; String Create_Robot = "/admin/robot/create";
String CreateOrUpdate_Device = "/admin/device/create"; String CreateOrUpdate_Device = "/admin/device/create";
@@ -28,7 +29,9 @@ public interface APIPath {
String User_Get_Blocked_List = "/admin/user/get_blocked_list"; String User_Get_Blocked_List = "/admin/user/get_blocked_list";
String User_Check_Block_Status = "/admin/user/check_block_status"; String User_Check_Block_Status = "/admin/user/check_block_status";
String User_Get_Online_Status = "/admin/user/onlinestatus"; 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_Update_Status = "/admin/friend/status";
String Friend_Get_List = "/admin/friend/list"; String Friend_Get_List = "/admin/friend/list";
@@ -38,12 +41,15 @@ public interface APIPath {
String Friend_Set_Alias = "/admin/friend/set_alias"; String Friend_Set_Alias = "/admin/friend/set_alias";
String Friend_Send_Request = "/admin/friend/send_request"; String Friend_Send_Request = "/admin/friend/send_request";
String Friend_Get_Requests = "/admin/friend/get_requests"; String Friend_Get_Requests = "/admin/friend/get_requests";
String Relation_Get = "/admin/relation/get";
String Msg_Send = "/admin/message/send"; String Msg_Send = "/admin/message/send";
String Msg_Recall = "/admin/message/recall"; String Msg_Recall = "/admin/message/recall";
String Msg_Delete = "/admin/message/delete"; String Msg_Delete = "/admin/message/delete";
String Msg_Broadcast = "/admin/message/broadcast"; String Msg_Broadcast = "/admin/message/broadcast";
String Msg_Multicast = "/admin/message/multicast"; 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 Create_Group = "/admin/group/create";
String Group_Dismiss = "/admin/group/del"; String Group_Dismiss = "/admin/group/del";
@@ -58,7 +64,7 @@ public interface APIPath {
String Group_Mute_Member = "/admin/group/manager/mute"; String Group_Mute_Member = "/admin/group/manager/mute";
String Group_Allow_Member = "/admin/group/manager/allow"; String Group_Allow_Member = "/admin/group/manager/allow";
String Get_User_Groups = "/admin/group/of_user"; 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 Create_Channel = "/admin/channel/create";
String Get_System_Setting = "/admin/system/get_setting"; String Get_System_Setting = "/admin/system/get_setting";
@@ -73,4 +79,25 @@ public interface APIPath {
String Robot_User_Info = "/robot/user_info"; String Robot_User_Info = "/robot/user_info";
String Robot_Message_Send = "/robot/message/send"; 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";
} }
@@ -54,6 +54,7 @@ public enum ErrorCode {
ERROR_CODE_TIMEOUT(249, "timeout"), ERROR_CODE_TIMEOUT(249, "timeout"),
ERROR_CODE_OVER_FREQUENCY(250, "over frequency"), ERROR_CODE_OVER_FREQUENCY(250, "over frequency"),
INVALID_PARAMETER(251, "Invalid parameter"), INVALID_PARAMETER(251, "Invalid parameter"),
INVALID_ASYNC_HANDLING(252, "Async handling"),
ERROR_CODE_NOT_EXIST(253, "not exist"), ERROR_CODE_NOT_EXIST(253, "not exist"),
ERROR_CODE_NOT_IMPLEMENT(254, "not implement"), ERROR_CODE_NOT_IMPLEMENT(254, "not implement"),
@@ -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); 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() { public WFCMessage.MessageContent getQuitGroupNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_QUIT_GROUP); 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() { public WFCMessage.MessageContent getTransferGroupNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_TRANSFER_GROUP_OWNER); 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,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;
}
}
@@ -0,0 +1,18 @@
/*
* 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;
public class InputUpdateUserInfo {
//UpdateUserInfoMask
public int flag;
public InputOutputUserInfo userInfo;
}
@@ -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. * file that was distributed with this source code.
*/ */
package win.liyufan.im; package cn.wildfirechat.pojos;
public interface MyInfoType { public interface MyInfoType {
int Modify_DisplayName = 0; 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;
}
@@ -0,0 +1,8 @@
package cn.wildfirechat.pojos;
public class RelationUpdateEvent {
public String userId;
public String targetId;
public int type;
public String value;
}
@@ -0,0 +1,21 @@
/*
* 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 RobotCallbackPojo {
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
@@ -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 StringPairPojo {
private String first;
private String second;
public StringPairPojo() {
}
public StringPairPojo(String first, String second) {
this.first = first;
this.second = second;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getSecond() {
return second;
}
public void setSecond(String second) {
this.second = second;
}
}
@@ -12,6 +12,9 @@ public class UserOnlineStatus {
public long timestamp; public long timestamp;
public String packageName; public String packageName;
public UserOnlineStatus() {
}
public UserOnlineStatus(String userId, String clientId, int platform, int status, String packageName) { public UserOnlineStatus(String userId, String clientId, int platform, int status, String packageName) {
this.userId = userId; this.userId = userId;
this.clientId = clientId; this.clientId = clientId;

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