Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6d3eba8e6 | ||
|
|
19bd5e83e5 | ||
|
|
2cbbf0a516 | ||
|
|
f6e8cd4ca8 | ||
|
|
da74b9fa94 | ||
|
|
281fe4c955 | ||
|
|
adfa3d3031 | ||
|
|
6c34a9e512 | ||
|
|
0fd56ba61d | ||
|
|
01342174af | ||
|
|
4742b135a5 | ||
|
|
6466218836 | ||
|
|
a973a731e4 | ||
|
|
90449e08c6 | ||
|
|
5857a3fbd1 | ||
|
|
ae4d8a95ba | ||
|
|
9fa1370219 | ||
|
|
dd4cdb4bc4 | ||
|
|
e07b839671 | ||
|
|
3a0653b8ed | ||
|
|
b4979e5408 | ||
|
|
59cb884772 | ||
|
|
3d0a36b4f3 | ||
|
|
7923a3e0c4 | ||
|
|
e5a4aa4741 | ||
|
|
e76e8b38df | ||
|
|
5f7df37664 | ||
|
|
2c9e8d66e8 | ||
|
|
d7eddbf7b4 | ||
|
|
3b783fb72e | ||
|
|
4e9e87f113 | ||
|
|
0f0b3398d7 | ||
|
|
a725b507c7 | ||
|
|
46423a341d | ||
|
|
f70ae457af | ||
|
|
29b30cec28 | ||
|
|
fc05973b5d | ||
|
|
97a21ff201 | ||
|
|
0b90f0c56c | ||
|
|
07454aedce | ||
|
|
ee26284d39 | ||
|
|
99e24dca1c | ||
|
|
5dbfeaabf9 | ||
|
|
38595c06d8 | ||
|
|
e65e313ef3 | ||
|
|
4e5355af11 | ||
|
|
fa47de1904 | ||
|
|
4abf1ed941 | ||
|
|
9b0ca7ac3c | ||
|
|
772940e50d | ||
|
|
c63cc74028 | ||
|
|
76aff64a1b | ||
|
|
9502b01b49 | ||
|
|
5b476b205e | ||
|
|
d24d71d040 | ||
|
|
11b0e6454c | ||
|
|
31d69e78cf | ||
|
|
28b732788c | ||
|
|
2d1d5309bf | ||
|
|
6d9eeb25d6 | ||
|
|
32f63a7d9c | ||
|
|
4d903ca379 | ||
|
|
d233dbdd99 | ||
|
|
0f32aa30ce | ||
|
|
9e007185ba | ||
|
|
ab92bc116c | ||
|
|
4308e51357 | ||
|
|
59977fb1ba | ||
|
|
d912777974 | ||
|
|
19b7bc42ef | ||
|
|
e621bea8fa | ||
|
|
ca1cf03cc3 | ||
|
|
ed7e56ca75 | ||
|
|
40c5cd615d | ||
|
|
3438de39ad | ||
|
|
7f6b2d93df | ||
|
|
9c57a620c9 | ||
|
|
32252228b0 | ||
|
|
396351cc15 | ||
|
|
955c2182c8 | ||
|
|
823bd53da8 | ||
|
|
e4588bfd9d | ||
|
|
3b0f724ff0 | ||
|
|
94bc595757 | ||
|
|
139042c8e7 | ||
|
|
8e894e49b3 | ||
|
|
c30a688032 | ||
|
|
06bcfea16e | ||
|
|
52bbf57760 | ||
|
|
e63298f50b | ||
|
|
bc8baf3bcc | ||
|
|
30a62cfc58 | ||
|
|
35b8133046 | ||
|
|
4a8500b99b | ||
|
|
c26e98b960 | ||
|
|
70fcc66672 | ||
|
|
2538a6ca68 | ||
|
|
6388f1b89c | ||
|
|
ef1f25dab1 | ||
|
|
0a5c8a67bb | ||
|
|
ae3f0027ca | ||
|
|
76dedb3da7 | ||
|
|
580e9f80fb | ||
|
|
63304c5c5f | ||
|
|
c377360049 | ||
|
|
2e74a77e5b | ||
|
|
90286e9484 | ||
|
|
7f479dd9e5 | ||
|
|
bae0805e64 | ||
|
|
e5d63a8d5f | ||
|
|
06fe70bd6f | ||
|
|
5a14b2f2f0 | ||
|
|
fbe5bf7a77 | ||
|
|
4ae117dd6f | ||
|
|
4518beff28 | ||
|
|
3cc278211b | ||
|
|
355fc6cb06 | ||
|
|
aef125eb50 | ||
|
|
d89e641470 | ||
|
|
e41ae9a9e7 | ||
|
|
989f5aa190 | ||
|
|
a820300f04 | ||
|
|
68707560b9 | ||
|
|
bb5b6fac17 | ||
|
|
584eb094f3 | ||
|
|
b9b1a76d71 | ||
|
|
a40950fb8c | ||
|
|
a6fe4e9d6e | ||
|
|
6f06a499aa | ||
|
|
069770c411 | ||
|
|
1f5f7eb572 | ||
|
|
405ad6c121 | ||
|
|
ff6e94cee7 | ||
|
|
db6f273cba | ||
|
|
df3bace44b | ||
|
|
3f9a8be02c | ||
|
|
39eb08e3f2 | ||
|
|
22a4ef4f42 | ||
|
|
da0d2e22cc | ||
|
|
a80ef20da3 | ||
|
|
45fd11f641 | ||
|
|
cdc731a23b | ||
|
|
68a968a94c | ||
|
|
8604f4edf3 | ||
|
|
b1484b0c95 | ||
|
|
631986f7a2 | ||
|
|
db27e77303 | ||
|
|
5177779066 | ||
|
|
c4a764d81d | ||
|
|
2c5ae2bd86 | ||
|
|
b11d609ea0 | ||
|
|
b8170c4757 | ||
|
|
e42d6f8e4f | ||
|
|
e0c95bace9 | ||
|
|
8623223991 | ||
|
|
efdcc24067 | ||
|
|
ec18e40eb0 | ||
|
|
f9d970c730 | ||
|
|
590b02cc8e | ||
|
|
f2f75d3048 | ||
|
|
94466139f6 | ||
|
|
70aeff9ac5 | ||
|
|
7e56fe2ee0 | ||
|
|
599547d627 | ||
|
|
28600ea7f9 | ||
|
|
a73507c673 | ||
|
|
84b8d4cd09 | ||
|
|
b66aa3d634 | ||
|
|
508beaf62c | ||
|
|
e914afedf4 | ||
|
|
49c32d7fa1 | ||
|
|
aac106d37e | ||
|
|
8bd17a8093 | ||
|
|
b1f07f49ff | ||
|
|
86dddfd85f | ||
|
|
db733efc44 | ||
|
|
69f28bd35b |
@@ -1,13 +1,17 @@
|
||||
### Expected behavior
|
||||
## 提issue小提示
|
||||
为了尽快定位问题,需要提供足够的信息,请按照我们的要求格式来提问。***如果您不按照格式提问,我们将无法回复您的问题***
|
||||
|
||||
### Actual behavior
|
||||
#### 操作说明
|
||||
详细说明操作那个界面,每一步骤都要说得详细,如果是SDK或者api使用问题,需要详细说明调用的那个函数,参数都是什么。
|
||||
|
||||
### Steps to reproduce
|
||||
#### 表现现象
|
||||
描述一下什么现象,比如说函数返回error,errorcode是多少,或者界面上是什么状态,比如发送消息显示发送失败的红点。不要笼统的说功能有问题,不起作用。
|
||||
|
||||
### Minimal yet complete reproducer code (or URL to code) or complete log file
|
||||
#### 预期结果
|
||||
你认为正确的表现应该是什么样的。
|
||||
|
||||
### Moquette MQTT version
|
||||
#### 补充条件
|
||||
是否是毕现的,还是偶现的?是否只有在特殊的网络/设备/平台上出现,还是所有的都出现。还有您用的版本是什么时候的,是不是最新版
|
||||
|
||||
### JVM version (e.g. `java -version`)
|
||||
|
||||
### OS version (e.g. `uname -a`)
|
||||
#### demo对比结果
|
||||
请用demo对比测试,demo上是什么状态。
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
| [android-chat](https://github.com/wildfirechat/android-chat) | 野火IM Android 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平台应用 | |
|
||||
| [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 | |
|
||||
| [server](https://github.com/wildfirechat/server) | IM server | |
|
||||
| [app server](https://github.com/wildfirechat/app_server) | 应用服务端 | |
|
||||
@@ -16,7 +16,7 @@
|
||||
| [docs](https://github.com/wildfirechat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明 | | | |
|
||||
|
||||
# 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,支持我们坚持下去🙏🙏🙏🙏🙏
|
||||
@@ -43,11 +43,6 @@
|
||||
|
||||

|
||||
|
||||
#### 加入野火官方体验交流群
|
||||
使用野火IM移动客户端扫码下面二维码(不是使用微信扫码),和野火IM的爱好者一起畅谈野火IM的问题和经验:
|
||||
|
||||

|
||||
|
||||
#### 应用截图
|
||||

|
||||
|
||||
@@ -73,12 +68,12 @@
|
||||
|
||||
## 编译
|
||||
在安装JDK1.8以上及maven的前提下,在命令行中执行```mvn clean compile package```,生成的目标文件在```./distribution/target/distribution-xxxx-bundle-tar.tar.gz```
|
||||
> 由于使用了一个git的maven插件,如果本地没有git信息就会编译出错,请使用```git clone```的方法下载代码,或者下载压缩包解压后在根目录创建```.git```的空目录。建议用```git clone```的方式下载代码。
|
||||
|
||||
## 捐赠者名单
|
||||
|
||||
| 捐赠者 | 商标 | 金额 | 简介 |
|
||||
| ----- | ---- | -------- | --- |
|
||||
| [SAMOS](http://samos.io) |  | 保密 | 一站式区块链解决方案服务商(http://samos.io) |
|
||||
## 升级说明
|
||||
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相关业务。
|
||||
|
||||
@@ -20,9 +20,6 @@ port 1883
|
||||
##客户端短链接端口
|
||||
http_port 80
|
||||
|
||||
##WEB客户端长链接端口
|
||||
websocket_port 8083
|
||||
|
||||
#管理端口
|
||||
http.admin.port 18080
|
||||
|
||||
@@ -38,6 +35,11 @@ local_port 80
|
||||
##是否使用内置DB。0使用mysql;1使用h2db;2使用mysql+mongodb。社区版只支持0和1,专业版支持2
|
||||
embed.db 1
|
||||
|
||||
## 是否自动清理历史消息记录,当为true时,IM服务会定时扫描t_messages_x和t_user_messages_x表,清除掉3年前的历史消息。
|
||||
## 如果不开启自动清理,需要手动清理t_messages_x和t_user_messages_x表内的历史数据,保存数据不能超过3年。
|
||||
## 使用mongodb时次开关无效(因为mongodb设置了消息过期时间,会自动清理)。
|
||||
db.auto_clean_history_messages true
|
||||
|
||||
##服务器管理接口密钥
|
||||
http.admin.secret_key 123456
|
||||
|
||||
@@ -46,19 +48,18 @@ http.admin.secret_key 123456
|
||||
##这个地方上线前要改为false
|
||||
http.admin.no_check_time true
|
||||
|
||||
##客户端协议栈密钥,需要与客户端协议栈文件libemqq.cc文件中的aes_key值保持一致,16进制byte用逗号分割。这个密钥对安全性帮助不大,客户不要修改
|
||||
client.proto.secret_key 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F
|
||||
|
||||
##用来生产im token的私钥,只在服务器使用,客户端不用。正式使用时为了安全一定要修改这个值,切记切记
|
||||
token.key testim
|
||||
|
||||
##token的过期时间,单位为毫秒,默认为无限期。如果需要设置无限期,客户端上一定需要加上token过期的处理。token过期的处理请参考文档的常见问题
|
||||
##token.expire_time 2592000000
|
||||
|
||||
##首次登录,是否接收之前的历史消息。0 不接收;1接收。
|
||||
##首次登录,是否接收之前的历史消息。
|
||||
##0 不接收历史消息,只接收5分钟以内的消息,由于服务器没有保存已经收取记录,所以如果有超过5分钟之前未收取的消息也不会收取下拉;
|
||||
##1接收,会接收 message.max_queue 配置的条数的历史消息
|
||||
message.roaming 0
|
||||
|
||||
##是否开启拉取远程历史消息
|
||||
##是否开启拉取远程历史消息。如果为1,客户端在会话内如果本地消息读取完了,可以下拉继续加载在服务器上的该会话的消息;如果为0则不能。
|
||||
message.remote_history_message 0
|
||||
|
||||
##服务器为每个用户缓存的消息数量。这个值改得太大,拉取消息时间变长,另外会占用大量内存。
|
||||
@@ -67,13 +68,19 @@ message.max_queue 1024
|
||||
##是否禁止陌生人聊天
|
||||
message.disable_stranger_chat false
|
||||
|
||||
##黑名单处理策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃;2 敏感词替换为***;3 不处理。
|
||||
##所有命中敏感词的消息都会被记录在敏感词消息表中
|
||||
##黑名单策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃
|
||||
message.blacklist.strategy 0
|
||||
|
||||
##是否禁止服务器端消息搜索,该功能暂未实现。目前的影响是如果打开,则存储消息时不单独保存_searchable_content字段
|
||||
message.disable_remote_search false
|
||||
|
||||
##允许客户端撤回消息时限,单位是秒。群组管理员或群主撤回群成员消息、server api不受此限制,可以撤回任意时限内的消息
|
||||
message.recall_time_limit 120
|
||||
|
||||
## 禁止客户端发送消息类型,消息类型以逗号分开,下面3个值为示例,可以删除。
|
||||
## 一般用于重要类型消息,比如交易、充值等,禁止客户端发送,仅限于服务器发送,提高安全性。
|
||||
message.forbidden_client_send_types 3999,4000,4001
|
||||
|
||||
##禁止搜索用户
|
||||
friend.disable_search false
|
||||
|
||||
@@ -92,12 +99,30 @@ friend.reject_request_duration 2592000000
|
||||
##好友请求过期时间,单位是毫秒,默认是7天,0为不限制
|
||||
friend.request_expiration_duration 604800000
|
||||
|
||||
##添加好友后会发送欢迎消息,比如"你们已经是好友了,可以聊天了"。这个开关控制是用旧的方式还是用新的方式。
|
||||
##旧的方式会发送notification消息(contenttype是80),内容会根据好友接收者的语言选择对应的语言,如果双方语言不一致会导致另外一方看到的不是本地语言。
|
||||
##新的方式会发送添加好友消息(contenttype是93)和欢迎消息(contenttype是92),需要客户端实现这两种消息。
|
||||
##如果客户端已经实现这两种消息可以打开这个开关
|
||||
friend.new_welcome_message false
|
||||
|
||||
## 聊天室观众空闲退出时间,单位为毫秒,默认为15分钟,0为永远不退出
|
||||
chatroom.participant_idle_time 900000
|
||||
|
||||
## 用户向聊天室发送消息,自动加入聊天室
|
||||
chatroom.rejoin_when_active true
|
||||
|
||||
## 是否允许客户端发送操作群的自定义群通知消息
|
||||
group.allow_client_custom_operation_notification true
|
||||
|
||||
## 当群成员退出或者被移除时,是否同时给管理员和相关人员发送显式通知消息。
|
||||
## 0 不发送,1 退群时发送,2 踢人时发送,3 退群和踢人时都发送。
|
||||
group.visible_quit_or_kickoff_notification 0
|
||||
|
||||
## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开;
|
||||
## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。
|
||||
## 注意,修改本配置不会对已经同步的信息产生影响。
|
||||
#user.hide_properties 3,4,5
|
||||
|
||||
#*********************************************************************
|
||||
# hazelcase configuration
|
||||
#*********************************************************************
|
||||
@@ -106,7 +131,8 @@ hazelcast.configuration config/hazelcast.xml
|
||||
#*********************************************************************
|
||||
# Media server configuration
|
||||
#*********************************************************************
|
||||
##是否使用七牛云存储。1使用七牛;0使用内存文件服务器。
|
||||
##是否使用七牛云存储。1使用七牛;0使用内存文件服务器。默认的七牛账户信息不可用,请在七牛官网申请账户并配置
|
||||
## https://docs.wildfirechat.cn/server/media_server.html
|
||||
media.server.use_qiniu 0
|
||||
|
||||
##媒体类型分类
|
||||
@@ -146,47 +172,87 @@ qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn
|
||||
# 本地媒体服务器配置。
|
||||
local.media.storage.root media
|
||||
|
||||
# 是否支持多端登陆
|
||||
# 是否支持多端登陆,为true时支持任意平台任意多个客户端同时登录;为false时每个平台只支持一个端登录,但不同平台可以同时登录。
|
||||
server.multi_endpoint false
|
||||
|
||||
# 多平台连接状态通知(仅当multi_endpoint为false时有效)
|
||||
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。
|
||||
server.multi_platform_notification false
|
||||
|
||||
#*********************************************************************
|
||||
# Push server configuration
|
||||
#*********************************************************************
|
||||
##推送服务项目地址:https://github.com/wildfirechat/push_server。
|
||||
##安卓推送服务器地址
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
push.android.server.address http://localhost:8085/android/push
|
||||
|
||||
##苹果推送服务器地址
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
push.ios.server.address http://localhost:8085/ios/push
|
||||
|
||||
#*********************************************************************
|
||||
# User online status event callback
|
||||
# 监控配置
|
||||
#*********************************************************************
|
||||
##用户在线状态事件回调地址
|
||||
#user.online_status_callback http://localhost:8888/user/online_event
|
||||
#monitor.exception_event_address http://localhost:8888/im_exception_event/
|
||||
|
||||
#*********************************************************************
|
||||
# MongoDB configuration
|
||||
# 各种事件回调
|
||||
#*********************************************************************
|
||||
#专业版支持,社区版请忽略
|
||||
#mongodb.client_uri mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
|
||||
#mongodb.client_uri mongodb://host1:27017,host2:27017,host3:27017/wfchat?replicaSet=myReplicaSet
|
||||
mongodb.client_uri mongodb://wfc:123456@localhost:27017/wfchat
|
||||
mongodb.database wfchat
|
||||
mongodb.data_expire_days 1096
|
||||
##用户在线状态事件回调地址
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
#user.online_status_callback http://localhost:8888/im_event/user/online
|
||||
|
||||
##用户信息变动事件回调地址
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
#relation.relation_update_callback http://localhost:8888/im_event/user/relation
|
||||
|
||||
##用户信息变动事件回调地址
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
#user.user_info_update_callback http://localhost:8888/im_event/user/info
|
||||
|
||||
##消息转发地址
|
||||
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
|
||||
#message.forward.url http://localhost:8888/im_event/message
|
||||
##需要转发的消息类型,当有多个时以英文逗号分割。如果转发所有消息,请注释掉配置或者设置为空
|
||||
#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
|
||||
#*********************************************************************
|
||||
##文本敏感词过滤处理方法,0 发送失败;1 发送成功但消息被服务器直接丢弃;2 命中的敏感词被替换成***;3 记录并继续发送
|
||||
## 内置文本敏感词过滤处理方法,0 发送失败;1 发送成功但消息被服务器直接丢弃;2 命中的敏感词被替换成***;3 记录并继续发送
|
||||
sensitive.filter.type 0
|
||||
|
||||
#*********************************************************************
|
||||
# Message forward configuration
|
||||
#*********************************************************************
|
||||
##消息转发地址
|
||||
#message.forward.url http://localhost:8087/message/forward
|
||||
|
||||
##设备信息转发地址
|
||||
#things_message.forward.url http://localhost:8087/device/forward
|
||||
## 如果内置敏感词库无法满足您的需求,可以自己开发部署敏感词审核服务。配置如下地址和消息类型,IM服务会把指定消息类型的消息回调到指定地址
|
||||
## 审核服务返回状态码200表示继续发送,如果需要替换内容,返回状态码200并且内容为替换后的内容。返回403表示不允许发送。其它错误继续发送。
|
||||
## 独立审核服务地址,IM服务会post SendMessageData。如果需要修改消息内容,返回 MessagePayload。请参考应用服务中 "/message/censor" Mapping.
|
||||
#sensitive.remote_server_url http://192.168.3.202:8888/message/censor
|
||||
## 需要进行敏感词审核的消息类型,当有多个时以英文逗号分割
|
||||
#sensitive.remote_sensitive_message_type 1,2,3
|
||||
## 如果远程审核服务返回403,返回给发送端发送失败还是成功?实际上这个值影响发送响应是否等待审核结果,当为false时,消息发送给审核服务就立即返回
|
||||
## 成功给客户端。当为true时,消息发送给审核服务,等待审核结果,如果结果为继续发送就返回给客户端为成功,结果为禁止发送就返回失败给客户端。
|
||||
## 客户端操作的超时一般为10s左右,且考虑到复杂的网络情况,建议处理时间不要超过3s。建议这个值为false。
|
||||
#sensitive.remote_fail_when_matched false
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_read_report`;
|
||||
CREATE TABLE `t_read_report` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NULL,
|
||||
`_type` tinyint NULL,
|
||||
`_line` int(11) NULL,
|
||||
`_target` varchar(64) NULL,
|
||||
`_dt` bigint(20) NOT NULL DEFAULT 0,
|
||||
INDEX `read_report_index` (`_uid`, `_type`, `_line`, `_target`)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_read_report`;
|
||||
CREATE TABLE `t_user_read_report` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_rid` int(11) NOT NULL,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_seq` bigint(20) NOT NULL,
|
||||
`_dt` DATETIME NOT NULL DEFAULT NOW(),
|
||||
INDEX `user_read_report_index` (`_uid` DESC, `_seq` DESC),
|
||||
UNIQUE INDEX `user_read_report_index2` (`_uid` DESC, `_rid` DESC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_delivery_report`;
|
||||
CREATE TABLE `t_delivery_report` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `delivery_index` (`_uid`)
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_delivery_report`;
|
||||
CREATE TABLE `t_user_delivery_report` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_rid` varchar(64) NOT NULL,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_seq` bigint(20) NOT NULL,
|
||||
`_dt` DATETIME NOT NULL DEFAULT NOW(),
|
||||
INDEX `user_delivery_index` (`_uid` DESC, `_seq` DESC),
|
||||
UNIQUE INDEX `user_delivery_index2` (`_uid` DESC, `_rid` DESC)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
alter table t_group_member add column `_create_dt` bigint(20) DEFAULT 0;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table `t_group` add column `_history_message` tinyint NOT NULL DEFAULT 0;
|
||||
alter table `t_group` add column `_max_member_count` int(11) NOT NULL DEFAULT 2000;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table `t_settings` change column `value` `_value` varchar(64) NOT NULL;
|
||||
alter table `t_settings` change column `desc` `_desc` varchar(64) NOT NULL;
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_group` modify column `_searchable` int(11) NOT NULL DEFAULT 0;
|
||||
+15
@@ -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`)
|
||||
);
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
insert into t_user (`_uid`,`_name`,`_display_name`,`_portrait`,`_type`,`_dt`) values ('wfc_file_transfer','wfc_file_transfer','文件传输助手','https://static.wildfirechat.cn/wfc_file_transfer.png',1,1);
|
||||
insert into t_robot (`_uid`,`_owner`,`_secret`,`_callback`,`_state`,`_dt`) values ('wfc_file_transfer', 'wfc_file_transfer', '', '', 0, 1);
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_channel` modify column `_status` int(11) NOT NULL DEFAULT 0;
|
||||
@@ -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
+54
@@ -0,0 +1,54 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_read_report`;
|
||||
CREATE TABLE `t_read_report` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NULL,
|
||||
`_type` tinyint NULL,
|
||||
`_line` int(11) NULL,
|
||||
`_target` varchar(64) NULL,
|
||||
`_dt` bigint(20) NOT NULL DEFAULT 0,
|
||||
INDEX `read_report_index` (`_uid`, `_type`, `_line`, `_target`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_read_report`;
|
||||
CREATE TABLE `t_user_read_report` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_rid` int(11) NOT NULL,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_seq` bigint(20) NOT NULL,
|
||||
`_dt` DATETIME NOT NULL DEFAULT NOW(),
|
||||
INDEX `user_read_report_index` (`_uid` DESC, `_seq` DESC),
|
||||
UNIQUE INDEX `user_read_report_index2` (`_uid` DESC, `_rid` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_delivery_report`;
|
||||
CREATE TABLE `t_delivery_report` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `delivery_index` (`_uid`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_delivery_report`;
|
||||
CREATE TABLE `t_user_delivery_report` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_rid` varchar(64) NOT NULL,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_seq` bigint(20) NOT NULL,
|
||||
`_dt` DATETIME NOT NULL DEFAULT NOW(),
|
||||
INDEX `user_delivery_index` (`_uid` DESC, `_seq` DESC),
|
||||
UNIQUE INDEX `user_delivery_index2` (`_uid` DESC, `_rid` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1 @@
|
||||
alter table t_group_member add column `_create_dt` bigint(20) DEFAULT 0, COMMENT "group member create time";
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table `t_group` add column `_history_message` tinyint NOT NULL DEFAULT 0, COMMENT "new group member can load group history messages";
|
||||
alter table `t_group` add column `_max_member_count` int(11) NOT NULL DEFAULT 2000, COMMENT "max group member count";
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table `t_settings` change column `value` `_value` varchar(64) NOT NULL;
|
||||
alter table `t_settings` change column `desc` `_desc` varchar(64) NOT NULL;
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_group` modify column `_searchable` int(11) NOT NULL DEFAULT 0;
|
||||
+18
@@ -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,3 @@
|
||||
|
||||
insert into t_user (`_uid`,`_name`,`_display_name`,`_portrait`,`_type`,`_dt`) values ('wfc_file_transfer','wfc_file_transfer','文件传输助手','https://static.wildfirechat.cn/wfc_file_transfer.png',1,1);
|
||||
insert into t_robot (`_uid`,`_owner`,`_secret`,`_callback`,`_state`,`_dt`) values ('wfc_file_transfer', 'wfc_file_transfer', '', '', 0, 1);
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_channel` modify column `_status` int(11) NOT NULL DEFAULT 0;
|
||||
+129
@@ -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` );
|
||||
@@ -0,0 +1,6 @@
|
||||
程序会自动创建数据库和执行migrate里的数据库,不需要手动创建库和执行sql语句。
|
||||
|
||||
数据库版本管理使用了flyway,flyway进行数据库升级时会校验数据库脚本的有效性,如果修改过这里的脚本,下次升级时就会失败。
|
||||
|
||||
强烈不建议修改数据库表结构,如果有内容(比如默认用户或者默认机器人的属性)需要修改,可以等数据库升级完成后,通过命令行或者数据库客户端进行修改。
|
||||
由于服务具有缓存,一般修改过数据库内容后要重启后才能生效。
|
||||
+2
-9
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.41</version>
|
||||
<version>0.55</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
@@ -132,7 +132,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -198,13 +198,6 @@
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.46</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
|
||||
@@ -15,6 +15,7 @@ public class PushMessage {
|
||||
public int convType;
|
||||
public String target;
|
||||
public String targetName;
|
||||
public String userId;
|
||||
public int line;
|
||||
public int cntType;
|
||||
public long serverTime;
|
||||
@@ -23,6 +24,7 @@ public class PushMessage {
|
||||
//推送类型,android推送分为小米/华为/魅族等。ios分别为开发和发布。
|
||||
public int pushType;
|
||||
public String pushContent;
|
||||
public String pushData;
|
||||
public int unReceivedMsg;
|
||||
public int mentionedType;
|
||||
public String packageName;
|
||||
@@ -41,7 +43,16 @@ public class PushMessage {
|
||||
this.cntType = messageContentType;
|
||||
this.serverTime = serverTime;
|
||||
this.unReceivedMsg = unReceivedMsg;
|
||||
this.pushMessageType = (cntType == 400 ? PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE : (cntType == 402 ? PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE : PushServer.PushMessageType.PUSH_MESSAGE_TYPE_NORMAL));
|
||||
if (cntType == 400) {
|
||||
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE;
|
||||
} else if(cntType == 402) {
|
||||
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE;
|
||||
} else if(cntType == 401) {
|
||||
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_ANSWER;
|
||||
} else {
|
||||
this.pushMessageType = PushServer.PushMessageType.PUSH_MESSAGE_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
this.mentionedType = mentionedType;
|
||||
this.isHiddenDetail = isHiddenDetail;
|
||||
this.language = language;
|
||||
|
||||
@@ -8,12 +8,11 @@
|
||||
|
||||
package cn.wildfirechat.push;
|
||||
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import io.moquette.persistence.MemorySessionStore;
|
||||
import io.moquette.server.config.IConfig;
|
||||
import io.moquette.spi.ClientSession;
|
||||
import io.moquette.spi.ISessionsStore;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.slf4j.Logger;
|
||||
@@ -35,6 +34,7 @@ public class PushServer {
|
||||
int PUSH_MESSAGE_TYPE_VOIP_INVITE = 1;
|
||||
int PUSH_MESSAGE_TYPE_VOIP_BYE = 2;
|
||||
int PUSH_MESSAGE_TYPE_FRIEND_REQUEST = 3;
|
||||
int PUSH_MESSAGE_TYPE_VOIP_ANSWER = 4;
|
||||
}
|
||||
|
||||
private static PushServer INSTANCE = new PushServer();
|
||||
@@ -64,7 +64,7 @@ public class PushServer {
|
||||
pushMessageInternel(pushMessage, deviceId, pushContent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.PUSH_SERVER_Exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -90,6 +90,7 @@ public class PushServer {
|
||||
pushMessage.pushContent = pushContent;
|
||||
pushMessage.deviceToken = session.getDeviceToken();
|
||||
pushMessage.unReceivedMsg = badge;
|
||||
pushMessage.userId = session.getUsername();
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_Android) {
|
||||
String url = androidPushServerUrl;
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS) {
|
||||
|
||||
@@ -80,9 +80,12 @@ public class LoFileServer {
|
||||
|
||||
channel = b.bind(port).sync().channel();
|
||||
Logger.info("***** Welcome To LoServer on port [{}], startting spend {}ms *****", port, DateUtil.spendMs(start));
|
||||
} finally {
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Logger.error("端口 {} 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep {}", port, port);
|
||||
System.out.println("端口 " + port + " 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep " + port);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
public void shutdown() {
|
||||
if (this.channel != null) {
|
||||
|
||||
@@ -62,6 +62,7 @@ public class LoServer {
|
||||
|
||||
registerAllAction();
|
||||
|
||||
int bindingPort = port;
|
||||
try {
|
||||
final ServerBootstrap b = new ServerBootstrap();
|
||||
final ServerBootstrap adminB = new ServerBootstrap();
|
||||
@@ -87,6 +88,7 @@ public class LoServer {
|
||||
channel = b.bind(port).sync().channel();
|
||||
|
||||
|
||||
bindingPort = adminPort;
|
||||
adminB.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.option(ChannelOption.SO_BACKLOG, 10240) // 服务端可连接队列大小
|
||||
@@ -108,10 +110,14 @@ public class LoServer {
|
||||
|
||||
adminChannel = adminB.bind(adminPort).sync().channel();
|
||||
Logger.info("***** Welcome To LoServer on port [{},{}], startting spend {}ms *****", port, adminPort, DateUtil.spendMs(start));
|
||||
} finally {
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Logger.error("端口 {} 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep {}", bindingPort, bindingPort);
|
||||
System.out.println("端口 " + bindingPort + " 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep " + bindingPort);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
if (this.channel!= null) {
|
||||
this.channel.close();
|
||||
|
||||
@@ -109,7 +109,8 @@ public class FileAction extends Action {
|
||||
}
|
||||
|
||||
// 路径安全检查
|
||||
if (httpPath.contains("/.") || httpPath.contains("./") || httpPath.charAt(0) == '.' || httpPath.charAt(httpPath.length() - 1) == '.' || ReUtil.isMatch(INSECURE_URI, httpPath)) {
|
||||
String path = httpPath.substring(0, httpPath.lastIndexOf("/"));
|
||||
if (path.contains("/.") || path.contains("./") || ReUtil.isMatch(INSECURE_URI, path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputAddFriendRequest;
|
||||
import cn.wildfirechat.pojos.InputUpdateAlias;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Friend_Send_Request)
|
||||
@HttpMethod("POST")
|
||||
public class AddFriendRequestAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputAddFriendRequest input = getRequestBody(request.getNettyRequest(), InputAddFriendRequest.class);
|
||||
|
||||
if (StringUtil.isNullOrEmpty(input.getUserId()) || StringUtil.isNullOrEmpty(input.getFriendUid())) {
|
||||
sendResponse(response, ErrorCode.INVALID_PARAMETER, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
WFCMessage.AddFriendRequest addFriendRequest = WFCMessage.AddFriendRequest.newBuilder().setReason(input.getReason()).setTargetUid(input.getFriendUid()).build();
|
||||
RPCCenter.getInstance().sendRequest(input.getUserId(), null, IMTopic.AddFriendRequestTopic, addFriendRequest.toByteArray(), input.getUserId(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
sendResponse(response, null, null);
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, input.isForce());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -44,9 +44,20 @@ abstract public class AdminAction extends Action {
|
||||
if (!mLimitCounter.isGranted("admin")) {
|
||||
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
}
|
||||
|
||||
String nonce = request.getHeader("nonce");
|
||||
if (StringUtil.isNullOrEmpty(nonce)) {
|
||||
nonce = request.getHeader("Nonce");
|
||||
}
|
||||
String timestamp = request.getHeader("timestamp");
|
||||
if (StringUtil.isNullOrEmpty(timestamp)) {
|
||||
timestamp = request.getHeader("Timestamp");
|
||||
}
|
||||
String sign = request.getHeader("sign");
|
||||
if (StringUtil.isNullOrEmpty(sign)) {
|
||||
sign = request.getHeader("Sign");
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(nonce) || StringUtil.isNullOrEmpty(timestamp) || StringUtil.isNullOrEmpty(sign)) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ public class CreateChannelAction extends AdminAction {
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
byte[] data = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.readBytes(data);
|
||||
String secret = new String(data);
|
||||
sendResponse(response, null, new OutputCreateChannel(inputCreateChannel.getTargetId(), secret));
|
||||
String channelId = new String(data);
|
||||
sendResponse(response, null, new OutputCreateChannel(channelId));
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
@@ -63,7 +64,7 @@ public class CreateRobotAction extends AdminAction {
|
||||
messagesStore.addUserInfo(newUser, inputCreateRobot.getPassword());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
|
||||
response.setContent(new Gson().toJson(result));
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
@@ -25,7 +26,6 @@ import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import win.liyufan.im.DBUtil;
|
||||
import win.liyufan.im.UUIDGenerator;
|
||||
import win.liyufan.im.Utility;
|
||||
|
||||
@@ -88,7 +88,7 @@ public class CreateUserAction extends AdminAction {
|
||||
messagesStore.addUserInfo(newUserBuilder.build(), inputCreateUser.getPassword());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
|
||||
response.setContent(new Gson().toJson(result));
|
||||
|
||||
@@ -16,7 +16,7 @@ import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputFriendRequest;
|
||||
import cn.wildfirechat.pojos.InputUpdateFriendStatusRequest;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -41,7 +41,7 @@ public class FriendRelationAction extends AdminAction {
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputFriendRequest friendAdd = getRequestBody(request.getNettyRequest(), InputFriendRequest.class);
|
||||
InputUpdateFriendStatusRequest friendAdd = getRequestBody(request.getNettyRequest(), InputUpdateFriendStatusRequest.class);
|
||||
if (friendAdd != null
|
||||
&& !StringUtil.isNullOrEmpty(friendAdd.getUserId())
|
||||
&& !StringUtil.isNullOrEmpty(friendAdd.getFriendUid())
|
||||
|
||||
@@ -23,6 +23,7 @@ import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.Friend_Get_List)
|
||||
@@ -40,6 +41,7 @@ public class FriendRelationGetAction extends AdminAction {
|
||||
InputUserId inputGetFriendList = getRequestBody(request.getNettyRequest(), InputUserId.class);
|
||||
List<FriendData> dataList = messagesStore.getFriendList(inputGetFriendList.getUserId(), null, 0);
|
||||
List<String> list = new ArrayList<>();
|
||||
dataList.sort(Comparator.comparingLong(FriendData::getTimestamp));
|
||||
for (FriendData data : dataList) {
|
||||
if (data.getState() == 0) {
|
||||
list.add(data.getFriendUid());
|
||||
|
||||
@@ -14,6 +14,7 @@ import cn.wildfirechat.pojos.InputGetGroup;
|
||||
import cn.wildfirechat.pojos.OutputGroupMemberList;
|
||||
import cn.wildfirechat.pojos.PojoGroupInfo;
|
||||
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;
|
||||
@@ -45,7 +46,7 @@ public class GetGroupMembersAction extends AdminAction {
|
||||
&& (!StringUtil.isNullOrEmpty(inputGetGroup.getGroupId()))) {
|
||||
|
||||
List<WFCMessage.GroupMember> members = new ArrayList<>();
|
||||
ErrorCode errorCode = messagesStore.getGroupMembers(inputGetGroup.getGroupId(), 0, members);
|
||||
ErrorCode errorCode = messagesStore.getGroupMembers(null, inputGetGroup.getGroupId(), 0, members);
|
||||
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
@@ -56,6 +57,9 @@ public class GetGroupMembersAction extends AdminAction {
|
||||
OutputGroupMemberList out = new OutputGroupMemberList();
|
||||
out.setMembers(new ArrayList<>());
|
||||
for (WFCMessage.GroupMember member : members) {
|
||||
if (member.getType() == ProtoConstants.GroupMemberType.GroupMemberType_Removed) {
|
||||
continue;
|
||||
}
|
||||
PojoGroupMember pm = new PojoGroupMember();
|
||||
pm.setMember_id(member.getMemberId());
|
||||
pm.setAlias(member.getAlias());
|
||||
|
||||
+52
@@ -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;
|
||||
}
|
||||
}
|
||||
Executable
+85
@@ -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;
|
||||
}
|
||||
}
|
||||
Executable
+84
@@ -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;
|
||||
}
|
||||
}
|
||||
+61
@@ -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;
|
||||
}
|
||||
}
|
||||
+65
@@ -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;
|
||||
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.action.Action;
|
||||
import com.xiaoleilu.loServer.action.admin.AdminAction;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.spi.impl.Utils;
|
||||
@@ -34,9 +34,21 @@ abstract public class ChannelAction extends Action {
|
||||
@Override
|
||||
public ErrorCode preAction(Request request, Response response) {
|
||||
String nonce = request.getHeader("nonce");
|
||||
if (StringUtil.isNullOrEmpty(nonce)) {
|
||||
nonce = request.getHeader("Nonce");
|
||||
}
|
||||
String timestamp = request.getHeader("timestamp");
|
||||
if (StringUtil.isNullOrEmpty(timestamp)) {
|
||||
timestamp = request.getHeader("Timestamp");
|
||||
}
|
||||
String sign = request.getHeader("sign");
|
||||
if (StringUtil.isNullOrEmpty(sign)) {
|
||||
sign = request.getHeader("Sign");
|
||||
}
|
||||
String cid = request.getHeader("cid");
|
||||
if (StringUtil.isNullOrEmpty(cid)) {
|
||||
cid = request.getHeader("Cid");
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(nonce) || StringUtil.isNullOrEmpty(timestamp) || StringUtil.isNullOrEmpty(sign) || StringUtil.isNullOrEmpty(cid)) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
@@ -51,7 +63,7 @@ abstract public class ChannelAction extends Action {
|
||||
ts = Long.parseLong(timestamp);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.CHANNEL_API_Exception);
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@@ -63,6 +75,10 @@ abstract public class ChannelAction extends Action {
|
||||
if (channelInfo == null) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(channelInfo.getSecret())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
String str = nonce + "|" + channelInfo.getSecret() + "|" + timestamp;
|
||||
String localSign = DigestUtils.sha1Hex(str);
|
||||
|
||||
+86
@@ -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;
|
||||
}
|
||||
}
|
||||
+95
@@ -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;
|
||||
}
|
||||
}
|
||||
+41
@@ -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;
|
||||
}
|
||||
}
|
||||
+86
@@ -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;
|
||||
}
|
||||
}
|
||||
+42
@@ -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;
|
||||
}
|
||||
}
|
||||
+70
@@ -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;
|
||||
}
|
||||
}
|
||||
+90
@@ -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;
|
||||
}
|
||||
}
|
||||
+86
@@ -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;
|
||||
}
|
||||
}
|
||||
+86
@@ -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;
|
||||
}
|
||||
}
|
||||
Executable
+86
@@ -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;
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputQuitGroup;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.action.admin.AdminAction;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Robot_Group_Member_Quit)
|
||||
@HttpMethod("POST")
|
||||
public class QuitGroupMemberAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputQuitGroup inputQuitGroup = getRequestBody(request.getNettyRequest(), InputQuitGroup.class);
|
||||
inputQuitGroup.setOperator(robot.getUid());
|
||||
if (inputQuitGroup.isValide()) {
|
||||
RPCCenter.getInstance().sendRequest(inputQuitGroup.getOperator(), null, IMTopic.QuitGroupTopic, inputQuitGroup.toProtoGroupRequest().toByteArray(), inputQuitGroup.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
sendResponse(response, null, null);
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, false);
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.action.Action;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.imhandler.IMHandler;
|
||||
import io.moquette.spi.impl.Utils;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
@@ -38,9 +38,22 @@ abstract public class RobotAction extends Action {
|
||||
@Override
|
||||
public ErrorCode preAction(Request request, Response response) {
|
||||
String nonce = request.getHeader("nonce");
|
||||
if (StringUtil.isNullOrEmpty(nonce)) {
|
||||
nonce = request.getHeader("Nonce");
|
||||
}
|
||||
String timestamp = request.getHeader("timestamp");
|
||||
if (StringUtil.isNullOrEmpty(timestamp)) {
|
||||
timestamp = request.getHeader("Timestamp");
|
||||
}
|
||||
String sign = request.getHeader("sign");
|
||||
if (StringUtil.isNullOrEmpty(sign)) {
|
||||
sign = request.getHeader("Sign");
|
||||
}
|
||||
String rid = request.getHeader("rid");
|
||||
if (StringUtil.isNullOrEmpty(rid)) {
|
||||
rid = request.getHeader("Rid");
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(nonce) || StringUtil.isNullOrEmpty(timestamp) || StringUtil.isNullOrEmpty(sign) || StringUtil.isNullOrEmpty(rid)) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
@@ -54,7 +67,7 @@ abstract public class RobotAction extends Action {
|
||||
ts = Long.parseLong(timestamp);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ROBOT_API_Exception);
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@@ -67,6 +80,10 @@ abstract public class RobotAction extends Action {
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(robot.getSecret())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
String str = nonce + "|" + robot.getSecret() + "|" + timestamp;
|
||||
String localSign = DigestUtils.sha1Hex(str);
|
||||
return localSign.equals(sign) ? ErrorCode.ERROR_CODE_SUCCESS : ErrorCode.ERROR_CODE_AUTH_FAILURE;
|
||||
@@ -95,7 +112,7 @@ abstract public class RobotAction extends Action {
|
||||
return t;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ROBOT_API_Exception);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
+51
@@ -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;
|
||||
}
|
||||
}
|
||||
+86
@@ -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;
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.IntStringPairPojo;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
import static cn.wildfirechat.pojos.MyInfoType.*;
|
||||
|
||||
@Route(APIPath.Robot_Update_Profile)
|
||||
@HttpMethod("POST")
|
||||
public class UpdateProfileAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
IntStringPairPojo input = getRequestBody(request.getNettyRequest(), IntStringPairPojo.class);
|
||||
|
||||
WFCMessage.User.Builder builder = messagesStore.getUserInfo(robot.getUid()).toBuilder();
|
||||
boolean modified = false;
|
||||
switch (input.getIntValue()) {
|
||||
case Modify_DisplayName:
|
||||
builder.setDisplayName(input.getStrValue());
|
||||
modified = true;
|
||||
break;
|
||||
case Modify_Gender:
|
||||
builder.setGender(Integer.parseInt(input.getStrValue()));
|
||||
modified = true;
|
||||
break;
|
||||
case Modify_Portrait:
|
||||
builder.setPortrait(input.getStrValue());
|
||||
modified = true;
|
||||
break;
|
||||
//不允许修改电话号码,如果修改电话号码必须通过admin进行修改
|
||||
// case Modify_Mobile:
|
||||
// builder.setMobile(input.getStrValue());
|
||||
// modified = true;
|
||||
// break;
|
||||
case Modify_Email:
|
||||
builder.setEmail(input.getStrValue());
|
||||
modified = true;
|
||||
break;
|
||||
case Modify_Address:
|
||||
builder.setAddress(input.getStrValue());
|
||||
modified = true;
|
||||
break;
|
||||
case Modify_Company:
|
||||
builder.setCompany(input.getStrValue());
|
||||
modified = true;
|
||||
break;
|
||||
case Modify_Social:
|
||||
builder.setSocial(input.getStrValue());
|
||||
modified = true;
|
||||
break;
|
||||
case Modify_Extra:
|
||||
builder.setExtra(input.getStrValue());
|
||||
modified = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.ok();
|
||||
if(modified) {
|
||||
try {
|
||||
messagesStore.updateUserInfo(builder.build());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result.setErrorCode(ErrorCode.ERROR_CODE_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
package com.xiaoleilu.loServer.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import com.xiaoleilu.hutool.lang.Singleton;
|
||||
import com.xiaoleilu.hutool.log.Log;
|
||||
import com.xiaoleilu.hutool.log.StaticLog;
|
||||
import com.xiaoleilu.loServer.ServerSetting;
|
||||
import com.xiaoleilu.loServer.action.Action;
|
||||
import com.xiaoleilu.loServer.action.UnknownErrorAction;
|
||||
@@ -53,7 +49,7 @@ abstract public class ActionHandler extends SimpleChannelInboundHandler<FullHttp
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(Logger, e);
|
||||
Utility.printExecption(Logger, e, IMExceptionEvent.EventType.SHORT_LINK_Exception);
|
||||
Action errorAction = ServerSetting.getErrorAction(ServerSetting.MAPPING_ERROR);
|
||||
request.putParam(UnknownErrorAction.ERROR_PARAM_NAME, e);
|
||||
response.setContent(e.toString());
|
||||
|
||||
@@ -11,8 +11,6 @@ import io.netty.util.CharsetUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.activation.MimetypesFileTypeMap;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_RANGE;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
|
||||
@@ -22,7 +20,6 @@ import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
||||
public class HttpResponseHelper {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(HttpResponseHelper.class);
|
||||
private static final MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
|
||||
|
||||
/**
|
||||
* sendResponse
|
||||
@@ -149,7 +146,7 @@ public static String getContentType(String fileName) {
|
||||
if (fileExtName.equals("png")) { // MimetypesFileTypeMap目前缺少png类型
|
||||
return "image/png";
|
||||
} else {
|
||||
return mimetypesFileTypeMap.getContentType(fileName);
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -357,8 +357,8 @@ public class Response {
|
||||
final DefaultHttpResponse defaultHttpResponse = new DefaultHttpResponse(httpVersion, status);
|
||||
|
||||
// headers
|
||||
final HttpHeaders httpHeaders = defaultHttpResponse.headers().add(headers);
|
||||
|
||||
HttpHeaders httpHeaders = defaultHttpResponse.headers().add(headers);
|
||||
httpHeaders.set(HttpHeaderNames.CONTENT_TYPE.toString(), contentType);
|
||||
// Cookies
|
||||
for (Cookie cookie : cookies) {
|
||||
httpHeaders.add(HttpHeaderNames.SET_COOKIE.toString(), ServerCookieEncoder.LAX.encode(cookie));
|
||||
|
||||
@@ -35,7 +35,6 @@ public final class BrokerConstants {
|
||||
public static final String DEFAULT_MOQUETTE_STORE_MAP_DB_FILENAME = "moquette_store.mapdb";
|
||||
public static final String DEFAULT_PERSISTENT_PATH = System.getProperty("user.dir") + File.separator
|
||||
+ DEFAULT_MOQUETTE_STORE_MAP_DB_FILENAME;
|
||||
public static final String WEB_SOCKET_PORT_PROPERTY_NAME = "websocket_port";
|
||||
public static final String WSS_PORT_PROPERTY_NAME = "secure_websocket_port";
|
||||
public static final String SSL_PORT_PROPERTY_NAME = "ssl_port";
|
||||
public static final String JKS_PATH_PROPERTY_NAME = "jks_path";
|
||||
@@ -47,7 +46,6 @@ public final class BrokerConstants {
|
||||
public static final String DB_AUTHENTICATOR_QUERY = "authenticator.db.query";
|
||||
public static final String DB_AUTHENTICATOR_DIGEST = "authenticator.db.digest";
|
||||
public static final int PORT = 1883;
|
||||
public static final int WEBSOCKET_PORT = 8080;
|
||||
public static final String DISABLED_PORT_BIND = "disabled";
|
||||
public static final String HOST = "0.0.0.0";
|
||||
public static final String NEED_CLIENT_AUTH = "need_client_auth";
|
||||
@@ -92,8 +90,22 @@ public final class BrokerConstants {
|
||||
public static final String PUSH_ANDROID_SERVER_ADDRESS = "push.android.server.address";
|
||||
public static final String PUSH_IOS_SERVER_ADDRESS = "push.ios.server.address";
|
||||
|
||||
public static final String MONITOR_Exception_Event_Address = "monitor.exception_event_address";
|
||||
|
||||
|
||||
public static final String USER_ONLINE_STATUS_CALLBACK = "user.online_status_callback";
|
||||
|
||||
public static final String GROUP_INFO_UPDATE_CALLBACK = "group.group_info_update_callback";
|
||||
public static final String GROUP_MEMBER_UPDATE_CALLBACK = "group.group_member_update_callback";
|
||||
public static final String RELATION_UPDATE_CALLBACK = "relation.relation_update_callback";
|
||||
public static final String USER_INFO_UPDATE_CALLBACK = "user.user_info_update_callback";
|
||||
|
||||
|
||||
public static final String CHANNEL_INFO_UPDATE_CALLBACK = "channel.channel_info_update_callback";
|
||||
public static final String CHATROOM_INFO_UPDATE_CALLBACK = "chatroom.chatroom_info_update_callback";
|
||||
public static final String CHATROOM_MEMBER_UPDATE_CALLBACK = "chatroom.chatroom_member_update_callback";
|
||||
|
||||
|
||||
public static final String HZ_Cluster_Node_External_IP = "node_external_ip";
|
||||
public static final String HZ_Cluster_Node_External_Long_Port = "node_external_long_port";
|
||||
public static final String HZ_Cluster_Node_External_Short_Port = "node_external_short_port";
|
||||
@@ -101,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_API_NO_CHECK_TIME = "http.admin.no_check_time";
|
||||
|
||||
public static final String CLIENT_PROTO_SECRET_KEY = "client.proto.secret_key";
|
||||
public static final String TOKEN_SECRET_KEY = "token.key";
|
||||
public static final String TOKEN_EXPIRE_TIME = "token.expire_time";
|
||||
|
||||
public static final String EMBED_DB_PROPERTY_NAME = "embed.db";
|
||||
|
||||
public static final String HZ_Cluster_Master_Node = "master_node";
|
||||
public static final String DB_AUTO_CLEAN_HISTORY_MESSAGES = "db.auto_clean_history_messages";
|
||||
|
||||
public static final String SENSITIVE_Filter_Type = "sensitive.filter.type";
|
||||
|
||||
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_Types = "message.forward.types";
|
||||
|
||||
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
|
||||
public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification";
|
||||
|
||||
public static final String MONGODB_Client_URI = "mongodb.client_uri";
|
||||
public static final String MONGODB_Database = "mongodb.database";
|
||||
public static final String MONGODB_Data_Expire_Days = "mongodb.data_expire_days";
|
||||
|
||||
public static final String MESSAGE_ROAMING = "message.roaming";
|
||||
public static final String MESSAGE_Remote_History_Message = "message.remote_history_message";
|
||||
|
||||
@@ -135,12 +146,22 @@ public final class BrokerConstants {
|
||||
public static final String FRIEND_Repeat_Request_Duration = "friend.repeat_request_duration";
|
||||
public static final String FRIEND_Reject_Request_Duration = "friend.reject_request_duration";
|
||||
public static final String FRIEND_Request_Expiration_Duration = "friend.request_expiration_duration";
|
||||
public static final String FRIEND_New_Welcome_Message = "friend.new_welcome_message";
|
||||
|
||||
public static final String CHATROOM_Participant_Idle_Time = "chatroom.participant_idle_time";
|
||||
public static final String CHATROOM_Rejoin_When_Active = "chatroom.rejoin_when_active";
|
||||
|
||||
public static final String GROUP_Allow_Client_Custom_Operation_Notification = "group.allow_client_custom_operation_notification";
|
||||
public static final String GROUP_Visible_Quit_Kickoff_Notification = "group.visible_quit_or_kickoff_notification";
|
||||
|
||||
public static final String USER_HIDE_PROPERTIES = "user.hide_properties";
|
||||
|
||||
public static final String MESSAGES_FORBIDDEN_CLIENT_SEND_TYPES = "message.forbidden_client_send_types";
|
||||
|
||||
public static final String MESSAGES_DISABLE_REMOTE_SEARCH = "message.disable_remote_search";
|
||||
|
||||
public static final String MESSAGES_RECALL_TIME_LIMIT = "message.recall_time_limit";
|
||||
|
||||
private BrokerConstants() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public class AddFriendHandler extends GroupHandler<WFCMessage.AddFriendRequest>
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.AddFriendRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
long[] head = new long[1];
|
||||
ErrorCode errorCode = m_messagesStore.saveAddFriendRequest(fromUser, request, head);
|
||||
ErrorCode errorCode = m_messagesStore.saveAddFriendRequest(fromUser, request, head, isAdmin);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
WFCMessage.User user = m_messagesStore.getUserInfo(request.getTargetUid());
|
||||
if (user != null && user.getType() == ProtoConstants.UserType.UserType_Normal) {
|
||||
|
||||
@@ -33,7 +33,13 @@ public class BroadcastMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
long messageId = MessageShardingUtil.generateId();
|
||||
long messageId = 0;
|
||||
try {
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ErrorCode.ERROR_CODE_SERVER_ERROR;
|
||||
}
|
||||
message = message.toBuilder().setFromUser(fromUser).setMessageId(messageId).setServerTimestamp(timestamp).setConversation(WFCMessage.Conversation.newBuilder().setTarget(fromUser).setLine(message.getConversation().getLine()).setType(ProtoConstants.ConversationType.ConversationType_Private).build()).build();
|
||||
|
||||
long count = saveAndBroadcast(fromUser, clientID, message);
|
||||
|
||||
@@ -27,9 +27,15 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
|
||||
return ErrorCode.ERROR_CODE_GROUP_ALREADY_EXIST;
|
||||
}
|
||||
}
|
||||
WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList());
|
||||
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), isAdmin);
|
||||
|
||||
if (groupInfo != null) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").getCreateGroupNotifyContent();
|
||||
|
||||
@@ -29,8 +29,12 @@ public class DismissGroupHandler extends GroupHandler<WFCMessage.DismissGroupReq
|
||||
} else if (isAdmin || (groupInfo.getType() == ProtoConstants.GroupType.GroupType_Normal || groupInfo.getType() == ProtoConstants.GroupType.GroupType_Restricted)
|
||||
&& groupInfo.getOwner() != null && groupInfo.getOwner().equals(fromUser)) {
|
||||
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
//send notify message first, then dismiss group
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, null, "").getDismissGroupNotifyContent();
|
||||
|
||||
@@ -24,7 +24,7 @@ public class GetGroupMemberHandler extends IMHandler<WFCMessage.PullGroupMemberR
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.PullGroupMemberRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
List<WFCMessage.GroupMember> members = new ArrayList<>();
|
||||
ErrorCode errorCode = m_messagesStore.getGroupMembers(request.getTarget(), request.getHead(), members);
|
||||
ErrorCode errorCode = m_messagesStore.getGroupMembers(fromUser, request.getTarget(), request.getHead(), members);
|
||||
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
WFCMessage.PullGroupMemberResult result = WFCMessage.PullGroupMemberResult.newBuilder().addAllMember(members).build();
|
||||
|
||||
@@ -22,7 +22,7 @@ public class GetUserInfoHandler extends IMHandler<WFCMessage.PullUserRequest> {
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.PullUserRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
WFCMessage.PullUserResult.Builder resultBuilder = WFCMessage.PullUserResult.newBuilder();
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.getUserInfo(request.getRequestList(), resultBuilder);
|
||||
ErrorCode errorCode = m_messagesStore.getUserInfo(fromUser, request.getRequestList(), resultBuilder);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
byte[] data = resultBuilder.build().toByteArray();
|
||||
ackPayload.ensureWritable(data.length).writeBytes(data);
|
||||
|
||||
@@ -13,12 +13,19 @@ import cn.wildfirechat.proto.WFCMessage;
|
||||
import win.liyufan.im.MessageShardingUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
abstract public class GroupHandler<T> extends IMHandler<T> {
|
||||
protected void sendGroupNotification(String fromUser, String targetId, List<Integer> lines, WFCMessage.MessageContent content) {
|
||||
if (lines != null) {
|
||||
sendGroupNotification(fromUser, targetId, lines, content, null);
|
||||
}
|
||||
|
||||
protected void sendGroupNotification(String fromUser, String targetId, List<Integer> lines, WFCMessage.MessageContent content, Collection<String> toUsers) {
|
||||
if (lines == null) {
|
||||
lines = new ArrayList<>();
|
||||
} else {
|
||||
lines = new ArrayList<>(lines);
|
||||
}
|
||||
|
||||
if (lines.isEmpty()) {
|
||||
@@ -30,9 +37,16 @@ abstract public class GroupHandler<T> extends IMHandler<T> {
|
||||
WFCMessage.Message.Builder builder = WFCMessage.Message.newBuilder().setContent(content).setServerTimestamp(timestamp);
|
||||
builder.setConversation(builder.getConversationBuilder().setType(ProtoConstants.ConversationType.ConversationType_Group).setTarget(targetId).setLine(line));
|
||||
builder.setFromUser(fromUser);
|
||||
long messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
saveAndPublish(fromUser, null, builder.build(), false);
|
||||
if(toUsers != null && !toUsers.isEmpty()) {
|
||||
builder.addAllTo(toUsers);
|
||||
}
|
||||
try {
|
||||
long messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
saveAndPublish(fromUser, null, builder.build());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,38 +32,54 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
|
||||
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
if (!isAdmin && builder.getConversation() != null && request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted) {
|
||||
long messageId = MessageShardingUtil.generateId();
|
||||
long timestamp = System.currentTimeMillis();
|
||||
builder.setMessageId(messageId);
|
||||
builder.setServerTimestamp(timestamp);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build(), false);
|
||||
try {
|
||||
long messageId = MessageShardingUtil.generateId();
|
||||
long timestamp = System.currentTimeMillis();
|
||||
builder.setMessageId(messageId);
|
||||
builder.setServerTimestamp(timestamp);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build());
|
||||
|
||||
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
|
||||
String language = "zh_CN";
|
||||
if (session != null && !StringUtil.isNullOrEmpty(session.getLanguage())) {
|
||||
language = session.getLanguage();
|
||||
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
|
||||
String language = "zh_CN";
|
||||
if (session != null && !StringUtil.isNullOrEmpty(session.getLanguage())) {
|
||||
language = session.getLanguage();
|
||||
}
|
||||
WFCMessage.MessageContent.Builder contentBuilder = WFCMessage.MessageContent.newBuilder();
|
||||
if (m_messagesStore.isNewFriendWelcomeMessage()) {
|
||||
contentBuilder.setType(92);
|
||||
} else {
|
||||
contentBuilder.setType(90).setContent(I18n.getString(language, "Above_Greeting_Message"));
|
||||
}
|
||||
|
||||
builder = WFCMessage.Message.newBuilder();
|
||||
builder.setFromUser(request.getTargetUid());
|
||||
builder.setConversation(WFCMessage.Conversation.newBuilder().setTarget(fromUser).setLine(0).setType(ProtoConstants.ConversationType.ConversationType_Private).build());
|
||||
builder.setContent(contentBuilder);
|
||||
timestamp = System.currentTimeMillis();
|
||||
builder.setServerTimestamp(timestamp);
|
||||
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build());
|
||||
|
||||
if (m_messagesStore.isNewFriendWelcomeMessage()) {
|
||||
contentBuilder.setType(93);
|
||||
} else {
|
||||
contentBuilder.setContent(I18n.getString(language, "Friend_Can_Start_Chat"));
|
||||
}
|
||||
|
||||
builder.setContent(contentBuilder);
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
timestamp = System.currentTimeMillis();
|
||||
builder.setServerTimestamp(timestamp);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
WFCMessage.MessageContent.Builder contentBuilder = WFCMessage.MessageContent.newBuilder().setType(90).setContent(I18n.getString(language, "Above_Greeting_Message"));
|
||||
|
||||
builder = WFCMessage.Message.newBuilder();
|
||||
builder.setFromUser(request.getTargetUid());
|
||||
builder.setConversation(WFCMessage.Conversation.newBuilder().setTarget(fromUser).setLine(0).setType(ProtoConstants.ConversationType.ConversationType_Private).build());
|
||||
builder.setContent(contentBuilder);
|
||||
timestamp = System.currentTimeMillis();
|
||||
builder.setServerTimestamp(timestamp);
|
||||
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build(), false);
|
||||
|
||||
contentBuilder.setContent(I18n.getString(language, "Friend_Can_Start_Chat"));
|
||||
builder.setContent(contentBuilder);
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
timestamp = System.currentTimeMillis();
|
||||
builder.setServerTimestamp(timestamp);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build(), false);
|
||||
|
||||
}
|
||||
if (request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted || isAdmin) {
|
||||
publisher.publishNotification(IMTopic.NotifyFriendTopic, request.getTargetUid(), heads[0]);
|
||||
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[1]);
|
||||
}
|
||||
|
||||
@@ -34,10 +34,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
@@ -207,8 +204,9 @@ abstract public class IMHandler<T> {
|
||||
errorCode = ErrorCode.ERROR_CODE_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
response(ackPayload, errorCode, callback);
|
||||
if(errorCode != ErrorCode.INVALID_ASYNC_HANDLING) {
|
||||
response(ackPayload, errorCode, callback);
|
||||
}
|
||||
} else {
|
||||
LOG.error("Handler {} preAction failure", this.getClass().getName());
|
||||
ByteBuf ackPayload = Unpooled.buffer(1);
|
||||
@@ -239,17 +237,17 @@ abstract public class IMHandler<T> {
|
||||
Set<String> notifyReceivers = new LinkedHashSet<>();
|
||||
|
||||
WFCMessage.Message.Builder messageBuilder = message.toBuilder();
|
||||
int pullType = m_messagesStore.getNotifyReceivers(username, messageBuilder, notifyReceivers, false);
|
||||
int pullType = m_messagesStore.getNotifyReceivers(username, messageBuilder, notifyReceivers);
|
||||
mServer.getImBusinessScheduler().execute(() -> this.publisher.publish2Receivers(messageBuilder.build(), notifyReceivers, clientID, pullType));
|
||||
return notifyReceivers.size();
|
||||
}
|
||||
|
||||
protected long saveAndPublish(String username, String clientID, WFCMessage.Message message, boolean ignoreMsg) {
|
||||
protected long saveAndPublish(String username, String clientID, WFCMessage.Message message) {
|
||||
Set<String> notifyReceivers = new LinkedHashSet<>();
|
||||
|
||||
message = m_messagesStore.storeMessage(username, clientID, message);
|
||||
WFCMessage.Message.Builder messageBuilder = message.toBuilder();
|
||||
int pullType = m_messagesStore.getNotifyReceivers(username, messageBuilder, notifyReceivers, ignoreMsg);
|
||||
int pullType = m_messagesStore.getNotifyReceivers(username, messageBuilder, notifyReceivers);
|
||||
mServer.getImBusinessScheduler().execute(() -> this.publisher.publish2Receivers(messageBuilder.build(), notifyReceivers, clientID, pullType));
|
||||
return notifyReceivers.size();
|
||||
}
|
||||
@@ -268,4 +266,13 @@ abstract public class IMHandler<T> {
|
||||
mServer.getImBusinessScheduler().execute(() -> publisher.publish2Receivers(updatedMessage, notifyReceivers, clientID, ProtoConstants.PullType.Pull_Normal));
|
||||
return notifyReceivers.size();
|
||||
}
|
||||
protected long publishRecallMultiCastMsg(long messageUid, List<String> receivers) {
|
||||
WFCMessage.Message updatedMessage = m_messagesStore.getMessage(messageUid);
|
||||
|
||||
Set<String> notifyReceivers = new HashSet<>(receivers);
|
||||
LOG.info("Multicast recall receiver count: {}", notifyReceivers.size());
|
||||
mServer.getImBusinessScheduler().execute(() -> publisher.publish2Receivers(updatedMessage, notifyReceivers, null, ProtoConstants.PullType.Pull_Normal));
|
||||
|
||||
return notifyReceivers.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ import cn.wildfirechat.pojos.GroupNotificationBinaryContent;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static win.liyufan.im.IMTopic.KickoffGroupMemberTopic;
|
||||
|
||||
@Handler(value = KickoffGroupMemberTopic)
|
||||
@@ -47,13 +50,24 @@ public class KickoffGroupMember extends GroupHandler<WFCMessage.RemoveGroupMembe
|
||||
if (!isAllow && (groupInfo.getType() == ProtoConstants.GroupType.GroupType_Normal || groupInfo.getType() == ProtoConstants.GroupType.GroupType_Restricted)) {
|
||||
errorCode = ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
} else {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
//send notify message first, then kickoff the member
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getRemovedMemberList()).getKickokfMemberGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
|
||||
}
|
||||
|
||||
if((m_messagesStore.getVisibleQuitKickoffNotification() & 0x02) > 0) {
|
||||
Set<String> toUsers = m_messagesStore.getGroupManagers(request.getGroupId(), true);
|
||||
toUsers.addAll(request.getRemovedMemberList());
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getRemovedMemberList()).getKickokfMemberVisibleGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content, toUsers);
|
||||
}
|
||||
errorCode = m_messagesStore.kickoffGroupMembers(fromUser, isAdmin, request.getGroupId(), request.getRemovedMemberList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,13 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
public class ModifyGroupAliasHandler extends GroupHandler<WFCMessage.ModifyGroupMemberAlias> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupMemberAlias request, Qos1PublishHandler.IMCallback callback) {
|
||||
ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias());
|
||||
if (errorCode == ERROR_CODE_SUCCESS && request.hasNotifyContent()) {
|
||||
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias(), null, isAdmin);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getAlias(), "").getModifyGroupMemberAliasNotifyContent();
|
||||
|
||||
@@ -22,9 +22,13 @@ import static win.liyufan.im.IMTopic.ModifyGroupInfoTopic;
|
||||
public class ModifyGroupInfoHandler extends GroupHandler<WFCMessage.ModifyGroupInfoRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupInfoRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
ErrorCode errorCode= m_messagesStore.modifyGroupInfo(fromUser, request.getGroupId(), request.getType(), request.getValue(), isAdmin);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = null;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.GroupNotificationBinaryContent;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(IMTopic.ModifyGroupMemberAliasTopic)
|
||||
public class ModifyGroupMemberAliasHandler extends GroupHandler<WFCMessage.ModifyGroupMemberAlias> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyGroupMemberAlias request, Qos1PublishHandler.IMCallback callback) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.modifyGroupAlias(fromUser, request.getGroupId(), request.getAlias(), request.getMemberId(), isAdmin);
|
||||
if (errorCode == ERROR_CODE_SUCCESS && request.hasNotifyContent()) {
|
||||
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getAlias(), request.getMemberId()).getModifyGroupMemberAliasNotifyContent();
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
|
||||
}
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,13 @@ public class MultiCastMessageHandler extends IMHandler<WFCMessage.MultiCastMessa
|
||||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
long messageId = MessageShardingUtil.generateId();
|
||||
long messageId = 0;
|
||||
try {
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ErrorCode.ERROR_CODE_SERVER_ERROR;
|
||||
}
|
||||
WFCMessage.Message message = WFCMessage.Message.newBuilder()
|
||||
.setContent(multiCastMessage.getContent())
|
||||
.setConversation(WFCMessage.Conversation.newBuilder().setTarget(fromUser).setType(ConversationType_Private).setLine(multiCastMessage.getLine()).build())
|
||||
|
||||
@@ -14,20 +14,32 @@ import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static win.liyufan.im.IMTopic.QuitGroupTopic;
|
||||
|
||||
@Handler(value = QuitGroupTopic)
|
||||
public class QuitGroupHandler extends GroupHandler<WFCMessage.QuitGroupRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.QuitGroupRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.quitGroup(fromUser, request.getGroupId());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getQuitGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
|
||||
}
|
||||
|
||||
if((m_messagesStore.getVisibleQuitKickoffNotification() & 0x01) > 0) {
|
||||
Set<String> toUsers = m_messagesStore.getGroupManagers(request.getGroupId(), true);
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getQuitVisibleGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content, toUsers);
|
||||
}
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
@Handler(value = IMTopic.RecallMultiCastMessageTopic)
|
||||
public class RecallMultiCastMessageHandler extends IMHandler<WFCMessage.RecallMultiCastMessageRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.RecallMultiCastMessageRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
if (!isAdmin) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.recallCastMessage(request.getMessageId(), fromUser);
|
||||
|
||||
if(errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
publishRecallMultiCastMsg(request.getMessageId(), request.getReceiverList());
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ package io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.hazelcast.core.Member;
|
||||
import io.moquette.persistence.MemorySessionStore;
|
||||
import io.moquette.spi.ClientSession;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -24,6 +25,19 @@ import static io.moquette.BrokerConstants.HZ_Cluster_Node_External_Short_Port;
|
||||
public class RouteHandler extends IMHandler<WFCMessage.RouteRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.RouteRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
MemorySessionStore.Session session = m_sessionsStore.sessionForClientAndUser(fromUser, clientID);
|
||||
if (session == null) {
|
||||
ErrorCode errorCode = m_sessionsStore.loadActiveSession(fromUser, clientID);
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
session = m_sessionsStore.sessionForClientAndUser(fromUser, clientID);
|
||||
}
|
||||
|
||||
if (session == null || session.getDeleted() > 0) {
|
||||
return ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH;
|
||||
}
|
||||
|
||||
Member member = mServer.getHazelcastInstance().getCluster().getLocalMember();
|
||||
String serverIp = member.getStringAttribute(HZ_Cluster_Node_External_IP);
|
||||
String longPort = member.getStringAttribute(HZ_Cluster_Node_External_Long_Port);
|
||||
|
||||
@@ -8,32 +8,51 @@
|
||||
|
||||
package io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import io.moquette.BrokerConstants;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import win.liyufan.im.HttpUtils;
|
||||
import win.liyufan.im.IMTopic;
|
||||
import win.liyufan.im.MessageShardingUtil;
|
||||
import win.liyufan.im.Utility;
|
||||
|
||||
import java.util.HashSet;
|
||||
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)
|
||||
public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
private int mSensitiveType = 0; //命中敏感词时,0 失败,1 吞掉, 2 敏感词替换成*。
|
||||
private String mForwardUrl = null;
|
||||
private Set<Integer> mForwardMessageTypes = new HashSet<>();
|
||||
private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。
|
||||
|
||||
private String mRemoteSensitiveServerUrl = null;
|
||||
private Set<Integer> mRemoteSensitiveMessageTypes;
|
||||
private boolean mWaitRemoteSensitiveServerResponse = false;
|
||||
|
||||
public SendMessageHandler() {
|
||||
super();
|
||||
|
||||
String forwardUrl = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_Url);
|
||||
if (!StringUtil.isNullOrEmpty(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 {
|
||||
@@ -49,6 +68,24 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
e.printStackTrace();
|
||||
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
|
||||
@@ -58,9 +95,14 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
boolean ignoreMsg = false;
|
||||
if (!isAdmin) { //admin do not check the right
|
||||
// 不能在端上直接发送撤回和群通知
|
||||
if (message.getContent().getType() == 80 || (message.getContent().getType() >= 100 && message.getContent().getType() < 200)) {
|
||||
if (message.getContent().getType() == 80 || message.getContent().getType() == 81 || (message.getContent().getType() >= 100 && message.getContent().getType() < 200)) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if(m_messagesStore.getClientForbiddenSendTypes().contains(message.getContent().getType())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
int userStatus = m_messagesStore.getUserStatus(fromUser);
|
||||
if (userStatus == ProtoConstants.UserStatus.Muted || userStatus == ProtoConstants.UserStatus.Forbidden) {
|
||||
return ErrorCode.ERROR_CODE_FORBIDDEN_SEND_MSG;
|
||||
@@ -100,37 +142,110 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
long messageId = MessageShardingUtil.generateId();
|
||||
final long messageId;
|
||||
try {
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ErrorCode.ERROR_CODE_SERVER_ERROR;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
if (!isAdmin) {
|
||||
Set<String> matched = m_messagesStore.handleSensitiveWord(message.getContent().getSearchableContent());
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
m_messagesStore.storeSensitiveMessage(message);
|
||||
if (mSensitiveType == 0) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
} else if(mSensitiveType == 1) {
|
||||
ignoreMsg = true;
|
||||
} else if(mSensitiveType == 2) {
|
||||
String text = message.getContent().getSearchableContent();
|
||||
for (String word : matched) {
|
||||
text = text.replace(word, "***");
|
||||
if(StringUtil.isNullOrEmpty(mRemoteSensitiveServerUrl)) {
|
||||
Set<String> matched = m_messagesStore.handleSensitiveWord(message.getContent().getSearchableContent());
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
m_messagesStore.storeSensitiveMessage(message);
|
||||
if (mSensitiveType == 0) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
} else if (mSensitiveType == 1) {
|
||||
ignoreMsg = true;
|
||||
} else if (mSensitiveType == 2) {
|
||||
String text = message.getContent().getSearchableContent();
|
||||
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();
|
||||
} else if(mSensitiveType == 3) {
|
||||
@Override
|
||||
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) {
|
||||
saveAndPublish(fromUser, clientID, message, ignoreMsg);
|
||||
if(!ignoreMsg) {
|
||||
saveAndPublish(fromUser, clientID, message);
|
||||
}
|
||||
ackPayload = ackPayload.capacity(20);
|
||||
ackPayload.writeLong(messageId);
|
||||
ackPayload.writeLong(timestamp);
|
||||
|
||||
@@ -21,9 +21,13 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
public class SetGroupManagerHandler extends GroupHandler<WFCMessage.SetGroupManagerRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.SetGroupManagerRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.setGroupManager(fromUser, request.getGroupId(), request.getType(), request.getUserIdList(), isAdmin);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getType() + "", request.getUserIdList()).getSetGroupManagerNotifyContent();
|
||||
|
||||
@@ -21,9 +21,13 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
public class TransferGroupHandler extends GroupHandler<WFCMessage.TransferGroupRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.TransferGroupRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && !isAdmin && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.transferGroup(fromUser, request.getGroupId(), request.getNewOwner(), isAdmin);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && (isAdmin || m_messagesStore.isAllowClientCustomGroupNotification())) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, request.getNewOwner()).getTransferGroupNotifyContent();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
package io.moquette.persistence;
|
||||
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import cn.wildfirechat.pojos.SystemSettingPojo;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
@@ -32,6 +33,7 @@ import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
|
||||
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*;
|
||||
@@ -72,7 +74,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -86,10 +88,10 @@ public class DatabaseStore {
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "insert into t_settings " +
|
||||
" (`id`, `value`, `desc`) values(?, ?, ?)" +
|
||||
" (`id`, `_value`, `_desc`) values(?, ?, ?)" +
|
||||
" ON DUPLICATE KEY UPDATE " +
|
||||
"`value` = ?," +
|
||||
"`desc` = ?";
|
||||
"`_value` = ?," +
|
||||
"`_desc` = ?";
|
||||
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
@@ -106,7 +108,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -120,7 +122,7 @@ public class DatabaseStore {
|
||||
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select `value`, `desc` from t_settings where `id` = ?";
|
||||
String sql = "select `_value`, `_desc` from t_settings where `id` = ?";
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
int index = 1;
|
||||
@@ -146,7 +148,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -203,10 +205,9 @@ public class DatabaseStore {
|
||||
}
|
||||
|
||||
if (page > 0) {
|
||||
sql += "offset = '" + page * 20 + "'";
|
||||
sql += " offset " + page * 20;
|
||||
}
|
||||
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
int index = 1;
|
||||
|
||||
@@ -286,7 +287,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -310,7 +311,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -331,7 +332,7 @@ public class DatabaseStore {
|
||||
String sql = "select `_mid`" +
|
||||
", `_alias`" +
|
||||
", `_type`" +
|
||||
", `_dt` from t_group_member where _gid = ?";
|
||||
", `_dt`, `_create_dt` from t_group_member where _gid = ?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
statement.setString(1, groupId);
|
||||
@@ -358,6 +359,9 @@ public class DatabaseStore {
|
||||
long longValue = rs.getLong(index++);
|
||||
builder.setUpdateDt(longValue);
|
||||
|
||||
longValue = rs.getLong(index++);
|
||||
builder.setCreateDt(longValue);
|
||||
|
||||
WFCMessage.GroupMember member = builder.build();
|
||||
groupMembers.put(groupId, member);
|
||||
}
|
||||
@@ -365,7 +369,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -421,7 +425,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -480,7 +484,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -553,7 +557,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -604,7 +608,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -665,10 +669,10 @@ public class DatabaseStore {
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
try {
|
||||
if (resultSet!=null) {
|
||||
@@ -676,14 +680,14 @@ public class DatabaseStore {
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, null);
|
||||
}
|
||||
@@ -721,7 +725,7 @@ public class DatabaseStore {
|
||||
}
|
||||
} catch (SQLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, resultSet);
|
||||
}
|
||||
@@ -741,7 +745,7 @@ public class DatabaseStore {
|
||||
LOG.info("Update rows {}", count);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -752,14 +756,22 @@ public class DatabaseStore {
|
||||
long[] before = new long[1];
|
||||
before[0] = beforeUid;
|
||||
boolean hasMore = loadRemoteMessagesFromTable(user, conversation, before, count, MessageShardingUtil.getMessageTable(beforeUid), messages);
|
||||
if (messages.size() < count) {
|
||||
if (hasMore) {
|
||||
loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), MessageShardingUtil.getMessageTable(beforeUid), messages);
|
||||
} else {
|
||||
String nexTable = MessageShardingUtil.getPreviousMessageTable(before[0]);
|
||||
if (!StringUtil.isNullOrEmpty(nexTable)) {
|
||||
loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), nexTable, messages);
|
||||
}
|
||||
while (messages.size() < count && hasMore) {
|
||||
hasMore = loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), MessageShardingUtil.getMessageTable(beforeUid), messages);
|
||||
}
|
||||
|
||||
int month = 0;
|
||||
while (messages.size() < count && !DBUtil.IsEmbedDB && month++ < 24) {
|
||||
String nexTable = MessageShardingUtil.getMessageTable(beforeUid, -month);
|
||||
|
||||
int size = messages.size();
|
||||
hasMore = true;
|
||||
while (size == messages.size() && hasMore) {
|
||||
hasMore = loadRemoteMessagesFromTable(user, conversation, before, count - messages.size(), nexTable, messages);
|
||||
}
|
||||
|
||||
if (size < messages.size()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,7 +835,16 @@ public class DatabaseStore {
|
||||
}
|
||||
}
|
||||
WFCMessage.Message message = builder.build();
|
||||
messages.add(message);
|
||||
boolean expired = false;
|
||||
if (message.getContent().getExpireDuration() > 0) {
|
||||
if (System.currentTimeMillis() > message.getServerTimestamp() + message.getContent().getExpireDuration()*1000) {
|
||||
expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!expired) {
|
||||
messages.add(message);
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
@@ -831,7 +852,7 @@ public class DatabaseStore {
|
||||
}
|
||||
} catch (SQLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, resultSet);
|
||||
}
|
||||
@@ -857,7 +878,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -885,12 +906,12 @@ public class DatabaseStore {
|
||||
statement = null;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -929,7 +950,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -966,7 +987,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -991,7 +1012,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1039,11 +1060,15 @@ public class DatabaseStore {
|
||||
|
||||
out.add(builder.build());
|
||||
}
|
||||
if (out.isEmpty()) {
|
||||
WFCMessage.UserSettingEntry.Builder builder = WFCMessage.UserSettingEntry.newBuilder().setScope(999).setKey("").setValue("").setUpdateDt(0);
|
||||
out.add(builder.build());
|
||||
}
|
||||
return out;
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -1080,7 +1105,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1111,7 +1136,6 @@ public class DatabaseStore {
|
||||
"`_type` = ?," +
|
||||
"`_extra` = ?," +
|
||||
"`_dt` = ?," +
|
||||
"`_member_count` = ?," +
|
||||
"`_mute` = ?" +
|
||||
", `_join_type` = ?" +
|
||||
", `_private_chat` = ?" +
|
||||
@@ -1142,7 +1166,6 @@ public class DatabaseStore {
|
||||
statement.setInt(index++, groupInfo.getType());
|
||||
statement.setString(index++, groupInfo.getExtra());
|
||||
statement.setLong(index++, groupInfo.getUpdateDt() == 0 ? System.currentTimeMillis() : groupInfo.getUpdateDt());
|
||||
statement.setInt(index++, groupInfo.getMemberCount());
|
||||
statement.setInt(index++, groupInfo.getMute());
|
||||
statement.setInt(index++, groupInfo.getJoinType());
|
||||
statement.setInt(index++, groupInfo.getPrivateChat());
|
||||
@@ -1153,7 +1176,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1196,7 +1219,7 @@ public class DatabaseStore {
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, resultSet);
|
||||
}
|
||||
@@ -1218,7 +1241,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1258,7 +1281,7 @@ public class DatabaseStore {
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, resultSet);
|
||||
}
|
||||
@@ -1291,7 +1314,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1330,7 +1353,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1338,7 +1361,6 @@ public class DatabaseStore {
|
||||
}
|
||||
|
||||
void updateSessionDeleted(String uid, String cid, int deleted) {
|
||||
mScheduler.execute(()->{
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
|
||||
@@ -1359,15 +1381,13 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void updateSessionPlatform(String uid, String cid, int platform) {
|
||||
mScheduler.execute(()->{
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
|
||||
@@ -1388,11 +1408,10 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean strEqual(String left, String right) {
|
||||
@@ -1480,7 +1499,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1530,7 +1549,36 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
}
|
||||
|
||||
void clearMultiUser(String uid, String clientId) {
|
||||
long start = System.currentTimeMillis();
|
||||
LOG.info("clearMultiUser {}, {}", uid, clientId);
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "update t_user_session set _deleted = ?, _token = ?, _voip_token = ?, _dt = ? where _cid = ? and _uid <> ? and _deleted = 0";
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
int index = 1;
|
||||
statement.setInt(index++, 1);
|
||||
statement.setString(index++, "");
|
||||
statement.setString(index++, "");
|
||||
statement.setLong(index++, System.currentTimeMillis());
|
||||
|
||||
statement.setString(index++, clientId);
|
||||
statement.setString(index++, uid);
|
||||
int count = statement.executeUpdate();
|
||||
LOG.info("Update rows {}", count);
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1571,7 +1619,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1584,12 +1632,10 @@ public class DatabaseStore {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select `_gid` from t_group_member where `_mid` = ? and `_type` <> ?";
|
||||
String sql = "select `_gid` from t_group_member where `_mid` = ? and `_type` <> 4";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
statement.setString(1, userId);
|
||||
statement.setInt(2, ProtoConstants.GroupMemberType.GroupMemberType_Removed);
|
||||
|
||||
|
||||
rs = statement.executeQuery();
|
||||
Set<String> out = new HashSet<>();
|
||||
@@ -1601,31 +1647,23 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
void updateGroupMemberCountDt(final String groupId, final int count, final long dt) {
|
||||
|
||||
void updateGroupMemberDt(final String groupId, final long dt) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
|
||||
String sql ;
|
||||
|
||||
if (count >= 0) {
|
||||
sql = "update t_group set `_member_count` = ?, `_member_dt` = ? , `_dt` = ? where `_gid` = ?";
|
||||
} else {
|
||||
sql = "update t_group set `_member_dt` = ?, `_dt` = ? where `_gid` = ?";
|
||||
}
|
||||
String sql = "update t_group set `_member_dt` = ?, `_dt` = ? where `_gid` = ?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
if (count >=0) {
|
||||
statement.setInt(index++, count);
|
||||
}
|
||||
statement.setLong(index++, dt);
|
||||
statement.setLong(index++, dt);
|
||||
statement.setString(index++, groupId);
|
||||
@@ -1635,7 +1673,30 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
}
|
||||
|
||||
void updateGroupMemberCountDt(final String groupId) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
|
||||
String sql = "update t_group set `_member_count` = (select count(*) from t_group_member where `_gid` = ? and `_type` <> 4 limit 1), `_dt` = ?, `_member_dt` = `_member_dt` + 1 where `_gid` = ?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
statement.setString(1, groupId);
|
||||
statement.setLong(2, System.currentTimeMillis());
|
||||
statement.setString(3, groupId);
|
||||
|
||||
int c = statement.executeUpdate();
|
||||
LOG.info("Update rows {}", c);
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1652,7 +1713,7 @@ public class DatabaseStore {
|
||||
", `_mid`" +
|
||||
", `_alias`" +
|
||||
", `_type`" +
|
||||
", `_dt`) values(?, ?, ?, ?, ?)" +
|
||||
", `_dt`, `_create_dt`) values(?, ?, ?, ?, ?, ?)" +
|
||||
" ON DUPLICATE KEY UPDATE " +
|
||||
"`_alias` = ?," +
|
||||
"`_type` = ?," +
|
||||
@@ -1673,6 +1734,7 @@ public class DatabaseStore {
|
||||
statement.setString(index++, member.getAlias());
|
||||
statement.setInt(index++, member.getType());
|
||||
statement.setLong(index++, dt);
|
||||
statement.setLong(index++, member.getCreateDt());
|
||||
statement.setString(index++, member.getAlias());
|
||||
statement.setInt(index++, member.getType());
|
||||
statement.setLong(index++, dt);
|
||||
@@ -1693,7 +1755,7 @@ public class DatabaseStore {
|
||||
}
|
||||
}
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1702,11 +1764,8 @@ public class DatabaseStore {
|
||||
int removeGroupMember(String groupId, List<String> groupMembers) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
PreparedStatement statement2 = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
StringBuilder sqlBuilder = new StringBuilder("update t_group_member set `_type` = ?, `_dt` = ? where `_mid` in (");
|
||||
for (int i = 0; i < groupMembers.size(); i++) {
|
||||
sqlBuilder.append("?");
|
||||
@@ -1715,9 +1774,7 @@ public class DatabaseStore {
|
||||
}
|
||||
}
|
||||
sqlBuilder.append(")");
|
||||
|
||||
sqlBuilder.append(" and _gid = ?");
|
||||
|
||||
statement = connection.prepareStatement(sqlBuilder.toString());
|
||||
|
||||
int index = 1;
|
||||
@@ -1729,36 +1786,14 @@ public class DatabaseStore {
|
||||
statement.setString(index++, memberId);
|
||||
}
|
||||
statement.setString(index++, groupId);
|
||||
|
||||
int count = statement.executeUpdate();
|
||||
LOG.info("Update rows {}", count);
|
||||
|
||||
String sql = "update t_group set `_member_count` = `_member_count` - ?, `_member_dt` = ? , `_dt` = ? where `_gid` = ?";
|
||||
|
||||
statement2 = connection.prepareStatement(sql);
|
||||
index = 1;
|
||||
statement2.setInt(index++, count);
|
||||
statement2.setLong(index++, current);
|
||||
statement2.setLong(index++, current);
|
||||
statement2.setString(index++, groupId);
|
||||
statement2.executeUpdate();
|
||||
connection.commit();
|
||||
connection.setAutoCommit(true);
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.commit();
|
||||
connection.setAutoCommit(true);
|
||||
} catch (SQLException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
DBUtil.closeDB(connection, statement2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1842,7 +1877,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -1894,7 +1929,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1918,7 +1953,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -1984,7 +2019,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -2018,7 +2053,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2041,7 +2076,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2063,7 +2098,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2119,7 +2154,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -2171,12 +2206,39 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
boolean isUidAndNameConflict(String uid, String name) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
long start = System.currentTimeMillis();
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select _uid from t_user where _name = ? and _uid <> ? limit 1";
|
||||
statement = connection.prepareStatement(sql);
|
||||
statement.setString(1, name);
|
||||
statement.setString(2, uid);
|
||||
rs = statement.executeQuery();
|
||||
if (rs.next()) {
|
||||
String conflictId = rs.getString(1);
|
||||
LOG.error("user {} already have name {} !!!", conflictId, name);
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void updateUser(final WFCMessage.User user) throws Exception {
|
||||
LOG.info("Database update user info {} {}", user.getUid(), user.getUpdateDt());
|
||||
@@ -2251,7 +2313,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
throw new Exception(e.getMessage());
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
@@ -2272,7 +2334,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2307,7 +2369,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2332,7 +2394,7 @@ public class DatabaseStore {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
}
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
@@ -2347,7 +2409,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
return -1;
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
@@ -2430,6 +2492,8 @@ public class DatabaseStore {
|
||||
builder.setDeleted(deleted);
|
||||
|
||||
long longValue = rs.getLong(index++);
|
||||
if(longValue <= 0)
|
||||
longValue = 1;
|
||||
builder.setUpdateDt(longValue);
|
||||
|
||||
return builder.build();
|
||||
@@ -2437,7 +2501,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -2460,7 +2524,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -2483,7 +2547,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -2511,7 +2575,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -2548,7 +2612,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -2573,7 +2637,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2595,7 +2659,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2664,7 +2728,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -2694,7 +2758,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2733,7 +2797,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2772,7 +2836,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2793,7 +2857,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2814,7 +2878,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2881,7 +2945,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2904,7 +2968,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -2984,7 +3048,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -3032,7 +3096,7 @@ public class DatabaseStore {
|
||||
}
|
||||
}
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -3063,7 +3127,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -3098,10 +3162,9 @@ public class DatabaseStore {
|
||||
|
||||
|
||||
if (page > 0) {
|
||||
sql += "offset = '" + page * 20 + "'";
|
||||
sql += " offset " + page * 20;
|
||||
}
|
||||
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
int index = 1;
|
||||
if (buzzy) {
|
||||
@@ -3150,7 +3213,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -3194,7 +3257,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -3221,7 +3284,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
@@ -3245,7 +3308,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
@@ -3268,7 +3331,7 @@ public class DatabaseStore {
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -57,6 +57,8 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
|
||||
private int deleted;
|
||||
|
||||
private boolean pullHistoryMsg;
|
||||
|
||||
public int getDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
@@ -139,6 +141,14 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
this.carrierName = carrierName;
|
||||
}
|
||||
|
||||
public boolean isPullHistoryMsg() {
|
||||
return pullHistoryMsg;
|
||||
}
|
||||
|
||||
public void setPullHistoryMsg(boolean pullHistoryMsg) {
|
||||
this.pullHistoryMsg = pullHistoryMsg;
|
||||
}
|
||||
|
||||
public long getUpdateDt() {
|
||||
return updateDt;
|
||||
}
|
||||
@@ -339,18 +349,22 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
Session session = sessions.get(clientID);
|
||||
|
||||
if (session != null && !session.username.equals(username)) {
|
||||
if (userSessions.get(username) != null) {
|
||||
userSessions.get(username).remove(clientID);
|
||||
if (userSessions.get(session.username) != null) {
|
||||
userSessions.get(session.username).remove(clientID);
|
||||
}
|
||||
session = null;
|
||||
}
|
||||
ClientSession clientSession = new ClientSession(clientID, this);
|
||||
session = databaseStore.getSession(username, clientID, clientSession);
|
||||
|
||||
if (session == null) {
|
||||
session = databaseStore.createSession(username, clientID, clientSession, platform);
|
||||
if(session == null) {
|
||||
session = databaseStore.getSession(username, clientID, clientSession);
|
||||
if (session == null) {
|
||||
session = databaseStore.createSession(username, clientID, clientSession, platform);
|
||||
}
|
||||
}
|
||||
sessions.put(clientID, session);
|
||||
|
||||
sessions.put(clientID, session);
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
|
||||
sessionSet.add(clientID);
|
||||
|
||||
if (session.getDeleted() > 0) {
|
||||
session.setDeleted(0);
|
||||
@@ -361,7 +375,7 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
session.setPlatform(platform);
|
||||
databaseStore.updateSessionPlatform(username, clientID, platform);
|
||||
}
|
||||
|
||||
databaseStore.clearMultiUser(username, clientID);
|
||||
|
||||
if (!supportMultiEndpoint && platform > 0) {
|
||||
databaseStore.clearMultiEndpoint(username, clientID, platform);
|
||||
@@ -393,8 +407,8 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
|
||||
if (remove) {
|
||||
sessions.remove(c);
|
||||
mServer.getProcessor().kickoffSession(s);
|
||||
it.remove();
|
||||
mServer.getProcessor().kickoffSession(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,6 +419,34 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kickoffUserClient(String username, String cid) {
|
||||
List<String> clientIds = new ArrayList<>();
|
||||
if(StringUtil.isNullOrEmpty(cid)) {
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
|
||||
clientIds.addAll(sessionSet);
|
||||
} else {
|
||||
clientIds.add(cid);
|
||||
}
|
||||
|
||||
for (String clientID: clientIds) {
|
||||
Session session = sessions.get(clientID);
|
||||
if(session == null) {
|
||||
ClientSession clientSession = new ClientSession(clientID, this);
|
||||
session = databaseStore.getSession(username, clientID, clientSession);
|
||||
if (session == null || session.getDeleted() > 0) {
|
||||
continue;
|
||||
}
|
||||
sessions.put(clientID, session);
|
||||
}
|
||||
|
||||
if (session.getDeleted() == 0) {
|
||||
session.setDeleted(1);
|
||||
databaseStore.updateSessionDeleted(username, clientID, 1);
|
||||
mServer.getProcessor().kickoffSession(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode loadActiveSession(String username, String clientID) {
|
||||
@@ -452,7 +494,6 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
|
||||
session.setUsername(username);
|
||||
sessions.put(clientID, session);
|
||||
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
|
||||
sessionSet.add(clientID);
|
||||
|
||||
@@ -491,11 +532,15 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
@Override
|
||||
public void loadUserSession(String username, String clientID) {
|
||||
if (sessions.containsKey(clientID)) {
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
|
||||
sessionSet.add(clientID);
|
||||
return;
|
||||
}
|
||||
Session session = databaseStore.getSession(username, clientID, new ClientSession(clientID, this));
|
||||
if (session != null) {
|
||||
sessions.put(clientID, session);
|
||||
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(username);
|
||||
sessionSet.add(clientID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ public class Server {
|
||||
|
||||
private ThreadPoolExecutorWrapper dbScheduler;
|
||||
private ThreadPoolExecutorWrapper imBusinessScheduler;
|
||||
private ThreadPoolExecutorWrapper callbackScheduler;
|
||||
|
||||
private IConfig mConfig;
|
||||
|
||||
@@ -225,7 +226,7 @@ public class Server {
|
||||
handlers = Collections.emptyList();
|
||||
}
|
||||
DBUtil.init(config);
|
||||
String strKey = config.getProperty(BrokerConstants.CLIENT_PROTO_SECRET_KEY);
|
||||
String strKey = "0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F";
|
||||
String[] strs = strKey.split(",");
|
||||
if(strs.length != 16) {
|
||||
LOG.error("Key error, it length should be 16");
|
||||
@@ -243,6 +244,7 @@ public class Server {
|
||||
int threadNum = Runtime.getRuntime().availableProcessors() * 2;
|
||||
dbScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(threadNum), threadNum, "db");
|
||||
imBusinessScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(threadNum), threadNum, "business");
|
||||
callbackScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(1), 1, "callback");
|
||||
|
||||
final String handlerProp = System.getProperty(BrokerConstants.INTERCEPT_HANDLER_PROPERTY_NAME);
|
||||
if (handlerProp != null) {
|
||||
@@ -251,6 +253,9 @@ public class Server {
|
||||
|
||||
initMediaServerConfig(config);
|
||||
|
||||
String monitorEventAddress = config.getProperty(MONITOR_Exception_Event_Address);
|
||||
Utility.setMonitorEventAddress(monitorEventAddress);
|
||||
|
||||
final String persistencePath = config.getProperty(BrokerConstants.PERSISTENT_STORE_PROPERTY_NAME);
|
||||
LOG.info("Configuring Using persistent store file, path={}", persistencePath);
|
||||
m_store = initStore(config, this);
|
||||
@@ -431,6 +436,7 @@ public class Server {
|
||||
System.out.println("Server will flush data to db before shutting down, please wait 5 seconds!");
|
||||
LOG.info("Unbinding server from the configured ports");
|
||||
m_shutdowning = true;
|
||||
DBUtil.SystemExiting = true;
|
||||
|
||||
m_acceptor.close();
|
||||
LOG.trace("Stopping MQTT protocol processor");
|
||||
@@ -447,6 +453,7 @@ public class Server {
|
||||
|
||||
dbScheduler.shutdown();
|
||||
imBusinessScheduler.shutdown();
|
||||
callbackScheduler.shutdown();
|
||||
|
||||
LOG.info("Moquette server has been stopped.");
|
||||
}
|
||||
@@ -507,4 +514,8 @@ public class Server {
|
||||
public ThreadPoolExecutorWrapper getImBusinessScheduler() {
|
||||
return imBusinessScheduler;
|
||||
}
|
||||
|
||||
public ThreadPoolExecutorWrapper getCallbackScheduler() {
|
||||
return callbackScheduler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,6 @@ public abstract class IConfig {
|
||||
void assignDefaults() {
|
||||
setProperty(BrokerConstants.PORT_PROPERTY_NAME, Integer.toString(BrokerConstants.PORT));
|
||||
setProperty(BrokerConstants.HOST_PROPERTY_NAME, BrokerConstants.HOST);
|
||||
// setProperty(BrokerConstants.WEB_SOCKET_PORT_PROPERTY_NAME,
|
||||
// Integer.toString(BrokerConstants.WEBSOCKET_PORT));
|
||||
// setProperty(BrokerConstants.PERSISTENT_STORE_PROPERTY_NAME,
|
||||
// BrokerConstants.DEFAULT_PERSISTENT_PATH);
|
||||
setProperty(BrokerConstants.AUTHORIZATOR_CLASS_NAME, "");
|
||||
}
|
||||
|
||||
|
||||
@@ -33,19 +33,6 @@ public class MemoryConfig extends IConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// private void createDefaults() {
|
||||
// m_properties.put(BrokerConstants.PORT_PROPERTY_NAME, Integer.toString(BrokerConstants.PORT));
|
||||
// m_properties.put(BrokerConstants.HOST_PROPERTY_NAME, BrokerConstants.HOST);
|
||||
// m_properties.put(BrokerConstants.WEB_SOCKET_PORT_PROPERTY_NAME,
|
||||
// Integer.toString(BrokerConstants.WEBSOCKET_PORT));
|
||||
// m_properties.put(BrokerConstants.PASSWORD_FILE_PROPERTY_NAME, "");
|
||||
// m_properties.put(BrokerConstants.PERSISTENT_STORE_PROPERTY_NAME,
|
||||
// BrokerConstants.DEFAULT_PERSISTENT_PATH);
|
||||
// m_properties.put(BrokerConstants.ALLOW_ANONYMOUS_PROPERTY_NAME, true);
|
||||
// m_properties.put(BrokerConstants.AUTHENTICATOR_CLASS_NAME, "");
|
||||
// m_properties.put(BrokerConstants.AUTHORIZATOR_CLASS_NAME, "");
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void setProperty(String name, String value) {
|
||||
m_properties.setProperty(name, value);
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.slf4j.LoggerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import java.io.IOException;
|
||||
import java.net.BindException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -57,35 +58,6 @@ import static io.netty.channel.ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE;
|
||||
|
||||
public class NettyAcceptor implements ServerAcceptor {
|
||||
|
||||
private static final String MQTT_SUBPROTOCOL_CSV_LIST = "mqtt, mqttv3.1, mqttv3.1.1";
|
||||
|
||||
static class WebSocketFrameToByteBufDecoder extends MessageToMessageDecoder<BinaryWebSocketFrame> {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext chc, BinaryWebSocketFrame frame, List<Object> out)
|
||||
throws Exception {
|
||||
// convert the frame to a ByteBuf
|
||||
ByteBuf bb = frame.content();
|
||||
// System.out.println("WebSocketFrameToByteBufDecoder decode - " +
|
||||
// ByteBufUtil.hexDump(bb));
|
||||
bb.retain();
|
||||
out.add(bb);
|
||||
}
|
||||
}
|
||||
|
||||
static class ByteBufToWebSocketFrameEncoder extends MessageToMessageEncoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext chc, ByteBuf bb, List<Object> out) throws Exception {
|
||||
// convert the ByteBuf to a WebSocketFrame
|
||||
BinaryWebSocketFrame result = new BinaryWebSocketFrame();
|
||||
// System.out.println("ByteBufToWebSocketFrameEncoder encode - " +
|
||||
// ByteBufUtil.hexDump(bb));
|
||||
result.content().writeBytes(bb);
|
||||
out.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class PipelineInitializer {
|
||||
|
||||
abstract void init(ChannelPipeline pipeline) throws Exception;
|
||||
@@ -144,17 +116,6 @@ public class NettyAcceptor implements ServerAcceptor {
|
||||
this.errorsCather = Optional.empty();
|
||||
|
||||
initializePlainTCPTransport(mqttHandler, props);
|
||||
String sslTcpPortProp = props.getProperty(BrokerConstants.SSL_PORT_PROPERTY_NAME);
|
||||
String wssPortProp = props.getProperty(BrokerConstants.WSS_PORT_PROPERTY_NAME);
|
||||
if (sslTcpPortProp != null || wssPortProp != null) {
|
||||
SSLContext sslContext = sslCtxCreator.initSSLContext();
|
||||
if (sslContext == null) {
|
||||
LOG.error("Can't initialize SSLHandler layer! Exiting, check your configuration of jks");
|
||||
return;
|
||||
}
|
||||
initializeSSLTCPTransport(mqttHandler, props, sslContext);
|
||||
initializeWSSTransport(mqttHandler, props, sslContext);
|
||||
}
|
||||
}
|
||||
|
||||
private void initFactory(String host, int port, String protocol, final PipelineInitializer pipeliner) {
|
||||
@@ -187,6 +148,11 @@ public class NettyAcceptor implements ServerAcceptor {
|
||||
f.sync().addListener(FIRE_EXCEPTION_ON_FAILURE);
|
||||
} catch (InterruptedException ex) {
|
||||
LOG.error("An interruptedException was caught while initializing server. Protocol={}", protocol, ex);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
LOG.error("端口 {} 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep {}", port, port);
|
||||
System.out.println("端口 " + port + " 已经被占用。请检查该端口被那个程序占用,找到程序停掉。\n查找端口被那个程序占用的命令是: netstat -tunlp | grep " + port);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,81 +191,6 @@ public class NettyAcceptor implements ServerAcceptor {
|
||||
});
|
||||
}
|
||||
|
||||
private void initializeSSLTCPTransport(final NettyMQTTHandler handler, IConfig props, final SSLContext sslContext)
|
||||
throws IOException {
|
||||
LOG.info("Configuring SSL MQTT transport");
|
||||
String sslPortProp = props.getProperty(SSL_PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
|
||||
if (DISABLED_PORT_BIND.equals(sslPortProp)) {
|
||||
// Do nothing no SSL configured
|
||||
LOG.info("Property {} has been set to {}. SSL MQTT will be disabled",
|
||||
BrokerConstants.SSL_PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
|
||||
return;
|
||||
}
|
||||
|
||||
int sslPort = Integer.parseInt(sslPortProp);
|
||||
LOG.info("Starting SSL on port {}", sslPort);
|
||||
|
||||
final MoquetteIdleTimeoutHandler timeoutHandler = new MoquetteIdleTimeoutHandler();
|
||||
String host = props.getProperty(BrokerConstants.HOST_PROPERTY_NAME);
|
||||
String sNeedsClientAuth = props.getProperty(BrokerConstants.NEED_CLIENT_AUTH, "false");
|
||||
final boolean needsClientAuth = Boolean.valueOf(sNeedsClientAuth);
|
||||
initFactory(host, sslPort, "SSL MQTT", new PipelineInitializer() {
|
||||
|
||||
@Override
|
||||
void init(ChannelPipeline pipeline) throws Exception {
|
||||
pipeline.addLast("ssl", createSslHandler(sslContext, needsClientAuth));
|
||||
pipeline.addFirst("idleStateHandler", new IdleStateHandler(nettyChannelTimeoutSeconds, 0, 0));
|
||||
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
|
||||
// pipeline.addLast("logger", new LoggingHandler("Netty", LogLevel.ERROR));
|
||||
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
|
||||
pipeline.addLast("decoder", new MqttDecoder());
|
||||
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
|
||||
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
|
||||
pipeline.addLast("messageLogger", new MQTTMessageLogger());
|
||||
pipeline.addLast("handler", handler);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initializeWSSTransport(final NettyMQTTHandler handler, IConfig props, final SSLContext sslContext)
|
||||
throws IOException {
|
||||
LOG.info("Configuring secure websocket MQTT transport");
|
||||
String sslPortProp = props.getProperty(WSS_PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
|
||||
if (DISABLED_PORT_BIND.equals(sslPortProp)) {
|
||||
// Do nothing no SSL configured
|
||||
LOG.info("Property {} has been set to {}. Secure websocket MQTT will be disabled",
|
||||
BrokerConstants.WSS_PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
|
||||
return;
|
||||
}
|
||||
int sslPort = Integer.parseInt(sslPortProp);
|
||||
final MoquetteIdleTimeoutHandler timeoutHandler = new MoquetteIdleTimeoutHandler();
|
||||
String host = props.getProperty(BrokerConstants.HOST_PROPERTY_NAME);
|
||||
String sNeedsClientAuth = props.getProperty(BrokerConstants.NEED_CLIENT_AUTH, "false");
|
||||
final boolean needsClientAuth = Boolean.valueOf(sNeedsClientAuth);
|
||||
initFactory(host, sslPort, "Secure websocket", new PipelineInitializer() {
|
||||
|
||||
@Override
|
||||
void init(ChannelPipeline pipeline) throws Exception {
|
||||
pipeline.addLast("ssl", createSslHandler(sslContext, needsClientAuth));
|
||||
pipeline.addLast("httpEncoder", new HttpResponseEncoder());
|
||||
pipeline.addLast("httpDecoder", new HttpRequestDecoder());
|
||||
pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
|
||||
pipeline.addLast("webSocketHandler",
|
||||
new WebSocketServerProtocolHandler("/org/fusesource/mqtt", MQTT_SUBPROTOCOL_CSV_LIST));
|
||||
pipeline.addLast("ws2bytebufDecoder", new WebSocketFrameToByteBufDecoder());
|
||||
pipeline.addLast("bytebuf2wsEncoder", new ByteBufToWebSocketFrameEncoder());
|
||||
pipeline.addFirst("idleStateHandler", new IdleStateHandler(nettyChannelTimeoutSeconds, 0, 0));
|
||||
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
|
||||
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
|
||||
pipeline.addLast("decoder", new MqttDecoder());
|
||||
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
|
||||
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
|
||||
pipeline.addLast("messageLogger", new MQTTMessageLogger());
|
||||
pipeline.addLast("handler", handler);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void close() {
|
||||
LOG.info("Closing Netty acceptor...");
|
||||
if (m_workerGroup == null || m_bossGroup == null) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package io.moquette.spi;
|
||||
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.SystemSettingPojo;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
@@ -30,6 +31,7 @@ import io.netty.handler.codec.mqtt.MqttQoS;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -99,36 +101,40 @@ public interface IMessagesStore {
|
||||
DatabaseStore getDatabaseStore();
|
||||
WFCMessage.Message storeMessage(String fromUser, String fromClientId, WFCMessage.Message message);
|
||||
void storeSensitiveMessage(WFCMessage.Message message);
|
||||
int getNotifyReceivers(String fromUser, WFCMessage.Message.Builder message, Set<String> notifyReceivers, boolean ignoreMsg);
|
||||
int getNotifyReceivers(String fromUser, WFCMessage.Message.Builder message, Set<String> notifyReceivers);
|
||||
Set<String> getAllEnds();
|
||||
WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType);
|
||||
WFCMessage.PullMessageResult loadRemoteMessages(String user, WFCMessage.Conversation conversation, long beforeUid, int count);
|
||||
long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String userId, long messageId);
|
||||
WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList);
|
||||
WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, boolean isAdmin);
|
||||
ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList);
|
||||
ErrorCode kickoffGroupMembers(String operator, boolean isAdmin, String groupId, List<String> memberList);
|
||||
ErrorCode quitGroup(String operator, String groupId);
|
||||
void clearUserGroups(String userId);
|
||||
ErrorCode dismissGroup(String operator, String groupId, boolean isAdmin);
|
||||
ErrorCode modifyGroupInfo(String operator, String groupId, int modifyType, String value, boolean isAdmin);
|
||||
ErrorCode modifyGroupAlias(String operator, String groupId, String alias);
|
||||
ErrorCode modifyGroupAlias(String operator, String groupId, String alias, String memberId, boolean isAdmin);
|
||||
List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests);
|
||||
WFCMessage.GroupInfo getGroupInfo(String groupId);
|
||||
Set<String> getUserGroupIds(String userId);
|
||||
ErrorCode getGroupMembers(String groupId, long maxDt, List<WFCMessage.GroupMember> members);
|
||||
ErrorCode getGroupMembers(String fromUser, String groupId, long maxDt, List<WFCMessage.GroupMember> members);
|
||||
WFCMessage.GroupMember getGroupMember(String groupId, String memberId);
|
||||
ErrorCode transferGroup(String operator, String groupId, String newOwner, boolean isAdmin);
|
||||
ErrorCode setGroupManager(String operator, String groupId, int type, List<String> userList, boolean isAdmin);
|
||||
boolean isMemberInGroup(String member, String groupId);
|
||||
ErrorCode canSendMessageInGroup(String member, String groupId);
|
||||
Set<String> getGroupManagers(String groupId, boolean includeOwner);
|
||||
|
||||
ErrorCode recallMessage(long messageUid, String operatorId, String clientId, boolean isAdmin);
|
||||
ErrorCode recallCastMessage(long messageUid, String operatorId);
|
||||
|
||||
void clearUserMessages(String userId);
|
||||
|
||||
WFCMessage.Robot getRobot(String robotId);
|
||||
void addRobot(WFCMessage.Robot robot);
|
||||
ErrorCode getUserInfo(List<WFCMessage.UserRequest> requestList, WFCMessage.PullUserResult.Builder builder);
|
||||
|
||||
ErrorCode getUserInfo(String fromUser, List<WFCMessage.UserRequest> requestList, WFCMessage.PullUserResult.Builder builder);
|
||||
|
||||
ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request) throws Exception;
|
||||
|
||||
void updateUserOnlineSetting(MemorySessionStore.Session session, boolean online);
|
||||
@@ -137,8 +143,10 @@ public interface IMessagesStore {
|
||||
int getUserStatus(String userId);
|
||||
List<InputOutputUserBlockStatus> getUserStatusList();
|
||||
|
||||
ErrorCode updateUserInfo(InputOutputUserInfo userInfo, int flag);
|
||||
void addUserInfo(WFCMessage.User user, String password) throws Exception;
|
||||
void destoryUser(String userId);
|
||||
void updateUserInfo(WFCMessage.User user) throws Exception;
|
||||
WFCMessage.User getUserInfo(String userId);
|
||||
WFCMessage.User getUserInfoByName(String name);
|
||||
WFCMessage.User getUserInfoByMobile(String mobile);
|
||||
@@ -159,14 +167,14 @@ public interface IMessagesStore {
|
||||
WFCMessage.PullMessageResult fetchChatroomMessage(String fromUser, String chatroomId, String exceptClientId, long fromMessageId);
|
||||
|
||||
ErrorCode verifyToken(String userId, String token, List<String> serverIPs, List<Integer> ports);
|
||||
ErrorCode login(String name, String password, List<String> userIdRet);
|
||||
|
||||
List<FriendData> getFriendList(String userId, String clientId, long version);
|
||||
void clearUserFriend(String userId);
|
||||
List<WFCMessage.FriendRequest> getFriendRequestList(String userId, long version);
|
||||
|
||||
ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head);
|
||||
ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin);
|
||||
ErrorCode handleFriendRequest(String userId, WFCMessage.HandleFriendRequest request, WFCMessage.Message.Builder msgBuilder, long[] heads, boolean isAdmin);
|
||||
boolean isNewFriendWelcomeMessage();
|
||||
ErrorCode deleteFriend(String userId, String friendUid, long[] head);
|
||||
ErrorCode blackUserRequest(String fromUser, String targetUserId, int status, long[] head);
|
||||
FriendData getFriendData(String fromUser, String targetUserId);
|
||||
@@ -184,11 +192,12 @@ public interface IMessagesStore {
|
||||
List<WFCMessage.UserSettingEntry> getUserSetting(String userId, int scope);
|
||||
long updateUserSettings(String userId, WFCMessage.ModifyUserSettingReq request);
|
||||
void clearUserSettings(String userId);
|
||||
boolean getUserGlobalSilent(String userId);
|
||||
|
||||
boolean getUserGlobalSlient(String userId);
|
||||
boolean getUserPushHiddenDetail(String userId);
|
||||
boolean getUserConversationSlient(String userId, WFCMessage.Conversation conversation);
|
||||
|
||||
boolean getUserConversationSilent(String userId, WFCMessage.Conversation conversation);
|
||||
boolean getSilentWhenPcOnline(String userId);
|
||||
boolean isUserNoDisturbing(String userId);
|
||||
ErrorCode createChannel(String operator, WFCMessage.ChannelInfo channelInfo);
|
||||
void clearUserChannels(String userId);
|
||||
ErrorCode modifyChannelInfo(String operator, String channelId, int modifyType, String value);
|
||||
@@ -206,6 +215,12 @@ public interface IMessagesStore {
|
||||
List<String> getAllSensitiveWords();
|
||||
|
||||
WFCMessage.Message getMessage(long messageId);
|
||||
|
||||
boolean isAllowClientCustomGroupNotification();
|
||||
int getVisibleQuitKickoffNotification();
|
||||
|
||||
List<Integer> getClientForbiddenSendTypes();
|
||||
|
||||
long getMessageHead(String user);
|
||||
long getFriendHead(String user);
|
||||
long getFriendRqHead(String user);
|
||||
|
||||
@@ -51,6 +51,8 @@ public interface ISessionsStore {
|
||||
void updateSessionToken(Session session, boolean voip);
|
||||
|
||||
void clearUserSession(String username);
|
||||
|
||||
void kickoffUserClient(String userId, String clientId);
|
||||
/**
|
||||
* @param clientID
|
||||
* the client owning the session.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package io.moquette.spi.impl;
|
||||
|
||||
import cn.wildfirechat.pojos.OutputMessageData;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import cn.wildfirechat.push.PushServer;
|
||||
@@ -24,11 +25,11 @@ import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import cn.wildfirechat.pojos.OutputNotifyChannelSubscribeStatus;
|
||||
import cn.wildfirechat.pojos.SendMessageData;
|
||||
import com.xiaoleilu.hutool.system.UserInfo;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
import io.moquette.persistence.*;
|
||||
import io.moquette.persistence.MemorySessionStore.Session;
|
||||
import io.moquette.server.ConnectionDescriptorStore;
|
||||
import io.moquette.server.Server;
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.moquette.spi.ISessionsStore;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -48,6 +49,7 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
|
||||
|
||||
public class MessagesPublisher {
|
||||
@@ -158,9 +160,9 @@ public class MessagesPublisher {
|
||||
}
|
||||
}
|
||||
|
||||
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageHead, Collection<String> receivers, String pushContent, 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) {
|
||||
publishTransparentMessage2Receivers(messageHead, receivers, pullType);
|
||||
publishTransparentMessage2Receivers(messageHead, receivers, pullType, exceptClientId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -175,7 +177,14 @@ public class MessagesPublisher {
|
||||
message = m_messagesStore.getMessage(messageHead);
|
||||
}
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
executorCallback.execute(() -> HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(SendMessageData.fromProtoMessage(finalMsg), SendMessageData.class)));
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(SendMessageData.fromProtoMessage(finalMsg), SendMessageData.class));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
}
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -197,6 +206,23 @@ public class MessagesPublisher {
|
||||
if (pullType == ProtoConstants.PullType.Pull_ChatRoom) {
|
||||
targetClients = m_messagesStore.getChatroomMemberClient(user);
|
||||
}
|
||||
boolean isPcOnline = false;
|
||||
|
||||
if (!user.equals(sender)) {
|
||||
for (Session targetSession : sessions) {
|
||||
if (targetSession.getPlatform() == ProtoConstants.Platform.Platform_WEB
|
||||
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_Windows
|
||||
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_LINUX
|
||||
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_OSX) {
|
||||
boolean targetIsActive = this.connectionDescriptors.isConnected(targetSession.getClientSession().clientID);
|
||||
if (targetIsActive) {
|
||||
isPcOnline = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Session targetSession : sessions) {
|
||||
//超过7天不活跃的用户忽略
|
||||
if(System.currentTimeMillis() - targetSession.getLastActiveTime() > 7 * 24 * 60 * 60 * 1000) {
|
||||
@@ -226,11 +252,13 @@ public class MessagesPublisher {
|
||||
}
|
||||
}
|
||||
|
||||
boolean isSlient;
|
||||
boolean isSilent;
|
||||
boolean isConvSilent = false;
|
||||
if (pullType == ProtoConstants.PullType.Pull_ChatRoom) {
|
||||
isSlient = true;
|
||||
isSilent = true;
|
||||
isConvSilent = true;
|
||||
} else {
|
||||
isSlient = false;
|
||||
isSilent = false;
|
||||
|
||||
if (!user.equals(sender)) {
|
||||
WFCMessage.Conversation conversation;
|
||||
@@ -240,29 +268,32 @@ public class MessagesPublisher {
|
||||
conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(target).build();
|
||||
}
|
||||
|
||||
|
||||
if (m_messagesStore.getUserConversationSlient(user, conversation)) {
|
||||
if (m_messagesStore.getUserConversationSilent(user, conversation)) {
|
||||
LOG.info("The conversation {}-{}-{} is slient", conversation.getType(), conversation.getTarget(), conversation.getLine());
|
||||
isSlient = true;
|
||||
isConvSilent = true;
|
||||
}
|
||||
|
||||
if (m_messagesStore.getUserGlobalSlient(user)) {
|
||||
if (m_messagesStore.getUserGlobalSilent(user)) {
|
||||
LOG.info("The user {} is global sliented", user);
|
||||
isSlient = true;
|
||||
isSilent = true;
|
||||
}
|
||||
|
||||
if (!isSilent && isPcOnline && m_messagesStore.getSilentWhenPcOnline(user)) {
|
||||
LOG.info("The user {} pc online and silent when pc online", user);
|
||||
isSilent = true;
|
||||
}
|
||||
|
||||
if (!isSilent && m_messagesStore.isUserNoDisturbing(user)) {
|
||||
LOG.info("The user {} is no disturbing", user);
|
||||
isSilent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtil.isNullOrEmpty(pushContent) || messageContentType == 400 || messageContentType == 402) {
|
||||
if (!isSlient) {
|
||||
if (!StringUtil.isNullOrEmpty(pushContent) || messageContentType == 400) {
|
||||
if (!isConvSilent && (persistFlag & 0x02) > 0) {
|
||||
targetSession.setUnReceivedMsgs(targetSession.getUnReceivedMsgs() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (isSlient) {
|
||||
if (mentionType == 2 || (mentionType == 1 && mentionTargets.contains(user))) {
|
||||
isSlient = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean needPush = !user.equals(sender);
|
||||
@@ -293,15 +324,15 @@ public class MessagesPublisher {
|
||||
int curMentionType = 0;
|
||||
if (mentionType == 2) {
|
||||
curMentionType = 2;
|
||||
isSlient = false;
|
||||
isConvSilent = false;
|
||||
} else if (mentionType == 1){
|
||||
if (mentionTargets != null && mentionTargets.contains(user)) {
|
||||
curMentionType = 1;
|
||||
isSlient = false;
|
||||
isConvSilent = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((StringUtil.isNullOrEmpty(pushContent) && messageContentType != 402 && messageContentType != 400)) {
|
||||
if ((StringUtil.isNullOrEmpty(pushContent) && messageContentType != 402 && messageContentType != 400 && messageContentType != 401)) {
|
||||
LOG.info("push content is empty and contenttype is {}", messageContentType);
|
||||
continue;
|
||||
}
|
||||
@@ -311,8 +342,13 @@ public class MessagesPublisher {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isSlient) {
|
||||
LOG.info("Slient of user or conversation");
|
||||
if (isConvSilent) {
|
||||
LOG.info("Silent of user or conversation");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isSilent) {
|
||||
LOG.info("Silent of user");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -331,14 +367,33 @@ public class MessagesPublisher {
|
||||
name = fd.getAlias();
|
||||
}
|
||||
}
|
||||
this.messageSender.sendPush(sender, conversationType, target, line, messageHead, targetSession.getClientID(), pushContent, messageContentType, serverTime, name, targetName, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
|
||||
this.messageSender.sendPush(sender, conversationType, target, line, messageHead, targetSession.getClientID(), pushContent, pushData, messageContentType, serverTime, name, targetName, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sendOfflineNotify(String clientId) {
|
||||
boolean targetIsActive = this.connectionDescriptors.isConnected(clientId);
|
||||
if (targetIsActive) {
|
||||
ByteBuf payload = Unpooled.buffer();
|
||||
payload.ensureWritable(1).writeBytes("1".getBytes());
|
||||
MqttPublishMessage publishMsg;
|
||||
publishMsg = notRetainedPublish(IMTopic.NotifyOffline, MqttQoS.AT_MOST_ONCE, payload);
|
||||
|
||||
private void publishTransparentMessage2Receivers(long messageHead, Collection<String> receivers, int pullType) {
|
||||
boolean sent = this.messageSender.sendPublish(clientId, publishMsg);
|
||||
if (sent) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
LOG.info("the target {} is not active", clientId);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void publishTransparentMessage2Receivers(long messageHead, Collection<String> receivers, int pullType, String exceptClientId) {
|
||||
WFCMessage.Message message = m_messagesStore.getMessage(messageHead);
|
||||
|
||||
if (message != null) {
|
||||
@@ -353,6 +408,9 @@ public class MessagesPublisher {
|
||||
if (targetSession.getClientID() == null) {
|
||||
continue;
|
||||
}
|
||||
if (targetSession.getClientID().equals(exceptClientId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean targetIsActive = this.connectionDescriptors.isConnected(targetSession.getClientSession().clientID);
|
||||
if (targetIsActive) {
|
||||
@@ -509,7 +567,14 @@ public class MessagesPublisher {
|
||||
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
|
||||
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
|
||||
executorCallback.execute(() -> HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(SendMessageData.fromProtoMessage(message), SendMessageData.class)));
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(SendMessageData.fromProtoMessage(message), SendMessageData.class));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
long messageId = message.getMessageId();
|
||||
@@ -544,18 +609,56 @@ public class MessagesPublisher {
|
||||
message.getConversation().getType(), message.getConversation().getTarget(), message.getConversation().getLine(),
|
||||
messageId,
|
||||
receivers,
|
||||
pushContent, exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag());
|
||||
pushContent, message.getContent().getPushData(), exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag());
|
||||
|
||||
}
|
||||
|
||||
public void forwardMessage(final WFCMessage.Message message, String forwardUrl) {
|
||||
executorCallback.execute(() -> HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(SendMessageData.fromProtoMessage(message), SendMessageData.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) {
|
||||
if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
|
||||
return;
|
||||
}
|
||||
executorCallback.execute(() -> HttpUtils.httpJsonPost(channelInfo.getCallback() + "/subscribe", new Gson().toJson(new OutputNotifyChannelSubscribeStatus(user, channelInfo.getTargetId(), listen), OutputNotifyChannelSubscribeStatus.class)));
|
||||
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/subscribe", new Gson().toJson(new OutputNotifyChannelSubscribeStatus(user, channelInfo.getTargetId(), listen), OutputNotifyChannelSubscribeStatus.class));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,11 @@ class PersistentQueueMessageSender {
|
||||
this.connectionDescriptorStore = connectionDescriptorStore;
|
||||
}
|
||||
|
||||
void sendPush(String sender, int conversationType, String target, int line, long messageHead, String deviceId, String pushContent, int messageContentType, long serverTime, String senderName, String targetName, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
|
||||
void sendPush(String sender, int conversationType, String target, int line, long messageHead, String deviceId, String pushContent, String pushData, int messageContentType, long serverTime, String senderName, String targetName, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
|
||||
LOG.info("Send push to {}, message from {}", deviceId, sender);
|
||||
PushMessage pushMessage = new PushMessage(sender, conversationType, target, line, messageContentType, serverTime, senderName, targetName, unReceivedMsg, mentionType, isHiddenDetail, language);
|
||||
pushMessage.pushContent = pushContent;
|
||||
pushMessage.pushData = pushData;
|
||||
PushServer.getServer().pushMessage(pushMessage, deviceId, pushContent);
|
||||
}
|
||||
|
||||
@@ -53,6 +54,10 @@ class PersistentQueueMessageSender {
|
||||
|
||||
boolean sendPublish(ClientSession clientsession, MqttPublishMessage pubMessage) {
|
||||
String clientId = clientsession.clientID;
|
||||
return sendPublish(clientId, pubMessage);
|
||||
}
|
||||
|
||||
boolean sendPublish(String clientId, MqttPublishMessage pubMessage) {
|
||||
final int messageId = pubMessage.variableHeader().packetId();
|
||||
final String topicName = pubMessage.variableHeader().topicName();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package io.moquette.spi.impl;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.SendMessageData;
|
||||
import cn.wildfirechat.pojos.UserOnlineStatus;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
@@ -54,6 +53,7 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static io.moquette.spi.impl.InternalRepublisher.createPublishForQos;
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
|
||||
import static io.moquette.spi.impl.Utils.readBytesAndRewind;
|
||||
import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.*;
|
||||
import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from;
|
||||
@@ -72,15 +72,30 @@ public class ProtocolProcessor {
|
||||
|
||||
public void kickoffSession(final MemorySessionStore.Session session) {
|
||||
mServer.getImBusinessScheduler().execute(()->{
|
||||
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID());
|
||||
try {
|
||||
if (descriptor != null) {
|
||||
processDisconnect(descriptor.getChannel(), true, false);
|
||||
new Thread(() -> {
|
||||
messagesPublisher.sendOfflineNotify(session.getClientID());
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
mServer.getImBusinessScheduler().execute(()->{
|
||||
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID());
|
||||
try {
|
||||
if (descriptor != null) {
|
||||
processDisconnect(descriptor.getChannel(), true, false);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
m_messagesStore.updateUserOnlineSetting(session, false);
|
||||
});
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,8 +188,7 @@ public class ProtocolProcessor {
|
||||
String clientId = payload.clientIdentifier();
|
||||
LOG.info("Processing CONNECT message. CId={}, username={}", clientId, payload.userName());
|
||||
|
||||
if (msg.variableHeader().version() < MqttVersion.MQTT_3_1_1.protocolLevel() ||
|
||||
msg.variableHeader().version() >= MqttVersion.Wildfire_Max.protocolLevel()) {
|
||||
if (msg.variableHeader().version() < MqttVersion.MQTT_3_1_1.protocolLevel()) {
|
||||
MqttConnAckMessage badProto = connAck(CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION);
|
||||
|
||||
LOG.error("MQTT protocol version is not valid. CId={}", clientId);
|
||||
@@ -243,18 +257,23 @@ public class ProtocolProcessor {
|
||||
MemorySessionStore.Session session = m_sessionsStore.getSession(clientId);
|
||||
if(session != null) {
|
||||
session.refreshLastActiveTime();
|
||||
forwardOnlineStatusEvent(payload.userName(), clientId, session.getPlatform(), UserOnlineStatus.ONLINE);
|
||||
forwardOnlineStatusEvent(payload.userName(), clientId, session.getPlatform(), UserOnlineStatus.ONLINE, session.getAppName());
|
||||
m_messagesStore.updateUserOnlineSetting(session, true);
|
||||
} else {
|
||||
forwardOnlineStatusEvent(payload.userName(), clientId, ProtoConstants.Platform.Platform_UNSET, UserOnlineStatus.ONLINE);
|
||||
}
|
||||
|
||||
LOG.info("The CONNECT message has been processed. CId={}, username={}", clientId, payload.userName());
|
||||
}
|
||||
|
||||
public void forwardOnlineStatusEvent(String userId, String clientId, int platform, int status) {
|
||||
public void forwardOnlineStatusEvent(String userId, String clientId, int platform, int status, String packageName) {
|
||||
if (!StringUtil.isNullOrEmpty(mUserOnlineStatusCallback)) {
|
||||
executorCallback.execute(() -> HttpUtils.httpJsonPost(mUserOnlineStatusCallback, new Gson().toJson(new UserOnlineStatus(userId, clientId, platform, status))));
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,9 +581,7 @@ public class ProtocolProcessor {
|
||||
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
|
||||
if(session != null) {
|
||||
m_messagesStore.updateUserOnlineSetting(session, false);
|
||||
}
|
||||
if(session != null) {
|
||||
forwardOnlineStatusEvent(username, clientID, session.getPlatform(), UserOnlineStatus.LOGOUT);
|
||||
forwardOnlineStatusEvent(username, clientID, session.getPlatform(), UserOnlineStatus.LOGOUT, session.getAppName());
|
||||
}
|
||||
|
||||
channel.closeFuture();
|
||||
@@ -608,7 +625,7 @@ public class ProtocolProcessor {
|
||||
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
|
||||
if(session != null) {
|
||||
session.refreshLastActiveTime();
|
||||
forwardOnlineStatusEvent(username, clientID, session.getPlatform(), clearSession ? UserOnlineStatus.LOGOUT : UserOnlineStatus.OFFLINE);
|
||||
forwardOnlineStatusEvent(username, clientID, session.getPlatform(), clearSession ? UserOnlineStatus.LOGOUT : UserOnlineStatus.OFFLINE, session.getAppName());
|
||||
m_messagesStore.updateUserOnlineSetting(session, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
|
||||
package io.moquette.spi.impl;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.*;
|
||||
import static io.moquette.spi.impl.Utils.readBytesAndRewind;
|
||||
import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from;
|
||||
import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_NOT_IMPLEMENT;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -256,6 +254,13 @@ public class Qos1PublishHandler extends QosPublishHandler {
|
||||
String imtopic = topic.getTopic();
|
||||
ByteBuf payload = msg.payload();
|
||||
byte[] payloadContent = readBytesAndRewind(payload);
|
||||
if(payloadContent.length == 0) {
|
||||
ByteBuf ackPayload = Unpooled.buffer();
|
||||
ackPayload.ensureWritable(1).writeByte(ERROR_CODE_INVALID_DATA.getCode());
|
||||
sendPubAck(clientID, messageID, ackPayload, ERROR_CODE_INVALID_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
MemorySessionStore.Session session = m_sessionStore.getSession(clientID);
|
||||
payloadContent = AES.AESDecrypt(payloadContent, session.getSecret(), true);
|
||||
imHandler(clientID, username, imtopic, payloadContent, (errorCode, ackPayload) -> sendPubAck(clientID, messageID, ackPayload, errorCode), false);
|
||||
|
||||
@@ -27,7 +27,7 @@ public enum MqttVersion {
|
||||
MQTT_3_1_1("MQTT", (byte) 4),
|
||||
Wildfire_1("MQTT", (byte) 5),
|
||||
Wildfire_2("MQTT", (byte) 6),
|
||||
Wildfire_Max("MQTT", (byte) 7);
|
||||
Wildfire_Future("MQTT", (byte) 7);
|
||||
|
||||
private final String name;
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -68,6 +71,9 @@ public enum MqttVersion {
|
||||
return mv;
|
||||
}
|
||||
}
|
||||
if(protocolLevel > Wildfire_Future.level) {
|
||||
return Wildfire_Future;
|
||||
}
|
||||
throw new MqttUnacceptableProtocolVersionException(protocolLevel + "is unknown protocol level");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.hazelcast.util.StringUtil;
|
||||
@@ -27,6 +29,8 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
|
||||
|
||||
public class DBUtil {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DBUtil.class);
|
||||
private static ComboPooledDataSource comboPooledDataSource = null;
|
||||
@@ -39,118 +43,226 @@ public class DBUtil {
|
||||
}
|
||||
};
|
||||
|
||||
public static boolean IsEmbedDB = false;
|
||||
public static boolean IsEmbedDB = false;
|
||||
public static boolean SystemExiting = false;
|
||||
public static boolean ClearDBDebugMode = false;
|
||||
|
||||
public static void init(IConfig config) {
|
||||
String embedDB = config.getProperty(BrokerConstants.EMBED_DB_PROPERTY_NAME);
|
||||
if (embedDB != null && embedDB.equals("1")) {
|
||||
IsEmbedDB = true;
|
||||
LOG.info("Use h2 database");
|
||||
public static void init(IConfig config) {
|
||||
String embedDB = config.getProperty(BrokerConstants.EMBED_DB_PROPERTY_NAME);
|
||||
boolean autoCleanMsgs = "true".equals(config.getProperty(BrokerConstants.DB_AUTO_CLEAN_HISTORY_MESSAGES));
|
||||
if (embedDB != null && embedDB.equals("1")) {
|
||||
IsEmbedDB = true;
|
||||
LOG.info("Use h2 database");
|
||||
} else {
|
||||
IsEmbedDB = false;
|
||||
LOG.info("Use mysql database");
|
||||
}
|
||||
|
||||
if (comboPooledDataSource == null) {
|
||||
String migrateLocation;
|
||||
if (IsEmbedDB) {
|
||||
migrateLocation = "filesystem:./migrate/h2";
|
||||
comboPooledDataSource = new ComboPooledDataSource();
|
||||
|
||||
comboPooledDataSource.setJdbcUrl( "jdbc:h2:./h2db/wfchat;AUTO_SERVER=TRUE;MODE=MySQL" );
|
||||
comboPooledDataSource.setUser("SA");
|
||||
comboPooledDataSource.setPassword("SA");
|
||||
comboPooledDataSource.setMinPoolSize(5);
|
||||
comboPooledDataSource.setAcquireIncrement(5);
|
||||
comboPooledDataSource.setMaxPoolSize(20);
|
||||
|
||||
comboPooledDataSource.setIdleConnectionTestPeriod(60 * 5);
|
||||
comboPooledDataSource.setMinPoolSize(3);
|
||||
comboPooledDataSource.setInitialPoolSize(3);
|
||||
|
||||
try {
|
||||
comboPooledDataSource.setDriverClass( "org.h2.Driver" ); //loads the jdbc driver
|
||||
} catch (PropertyVetoException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
System.exit(-1);
|
||||
}
|
||||
} else {
|
||||
IsEmbedDB = false;
|
||||
LOG.info("Use mysql database");
|
||||
}
|
||||
migrateLocation = "filesystem:./migrate/mysql";
|
||||
comboPooledDataSource = new ComboPooledDataSource("mysql");
|
||||
try {
|
||||
String url01 = comboPooledDataSource.getJdbcUrl().substring(0,comboPooledDataSource.getJdbcUrl().indexOf("?"));
|
||||
String datasourceName = url01.substring(url01.lastIndexOf("/")+1);
|
||||
// 连接已经存在的数据库,如:mysql
|
||||
String jdbc = comboPooledDataSource.getJdbcUrl().replace(datasourceName, "");
|
||||
Connection connection = DriverManager.getConnection(jdbc, comboPooledDataSource.getUser(), comboPooledDataSource.getPassword());
|
||||
Statement statement = connection.createStatement();
|
||||
|
||||
if (comboPooledDataSource == null) {
|
||||
String migrateLocation;
|
||||
if (IsEmbedDB) {
|
||||
migrateLocation = "filesystem:./migrate/h2";
|
||||
comboPooledDataSource = new ComboPooledDataSource();
|
||||
|
||||
comboPooledDataSource.setJdbcUrl( "jdbc:h2:./h2db/wfchat;AUTO_SERVER=TRUE;MODE=MySQL" );
|
||||
comboPooledDataSource.setUser("SA");
|
||||
comboPooledDataSource.setPassword("SA");
|
||||
comboPooledDataSource.setMinPoolSize(5);
|
||||
comboPooledDataSource.setAcquireIncrement(5);
|
||||
comboPooledDataSource.setMaxPoolSize(20);
|
||||
|
||||
comboPooledDataSource.setIdleConnectionTestPeriod(60 * 5);
|
||||
comboPooledDataSource.setMinPoolSize(3);
|
||||
comboPooledDataSource.setInitialPoolSize(3);
|
||||
|
||||
try {
|
||||
comboPooledDataSource.setDriverClass( "org.h2.Driver" ); //loads the jdbc driver
|
||||
} catch (PropertyVetoException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
System.exit(-1);
|
||||
}
|
||||
} else {
|
||||
migrateLocation = "filesystem:./migrate/mysql";
|
||||
comboPooledDataSource = new ComboPooledDataSource("mysql");
|
||||
try {
|
||||
String url01 = comboPooledDataSource.getJdbcUrl().substring(0,comboPooledDataSource.getJdbcUrl().indexOf("?"));
|
||||
String datasourceName = url01.substring(url01.lastIndexOf("/")+1);
|
||||
// 连接已经存在的数据库,如:mysql
|
||||
String jdbc = comboPooledDataSource.getJdbcUrl().replace(datasourceName, "");
|
||||
Connection connection = DriverManager.getConnection(jdbc, comboPooledDataSource.getUser(), comboPooledDataSource.getPassword());
|
||||
Statement statement = connection.createStatement();
|
||||
|
||||
// 创建数据库
|
||||
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS `" + datasourceName + "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
|
||||
|
||||
statement.close();
|
||||
connection.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
// 创建数据库
|
||||
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS `" + datasourceName + "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
|
||||
|
||||
statement.close();
|
||||
connection.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
Flyway flyway = Flyway.configure().dataSource(comboPooledDataSource).locations(migrateLocation).baselineOnMigrate(true).load();
|
||||
flyway.migrate();
|
||||
|
||||
}
|
||||
Flyway flyway = Flyway.configure().dataSource(comboPooledDataSource).locations(migrateLocation).baselineOnMigrate(true).load();
|
||||
flyway.migrate();
|
||||
|
||||
if(autoCleanMsgs) {
|
||||
cleanHistoryMsg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanHistoryMsg() {
|
||||
new Thread(()->{
|
||||
long usedTime = 0;
|
||||
while (true) {
|
||||
if(SystemExiting) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
long sleepTime;
|
||||
if(ClearDBDebugMode) {
|
||||
sleepTime = 60 * 1000 - usedTime;
|
||||
} else {
|
||||
sleepTime = 60 * 60 * 1000 - usedTime;
|
||||
}
|
||||
if(sleepTime < 0) {
|
||||
sleepTime = 5 * 1000;
|
||||
}
|
||||
|
||||
Thread.sleep(sleepTime);
|
||||
LOG.info("Start clean history messages");
|
||||
|
||||
if(SystemExiting) {
|
||||
break;
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
if(IsEmbedDB) {
|
||||
clearH2DB();
|
||||
} else {
|
||||
clearMySQL();
|
||||
}
|
||||
usedTime = System.currentTimeMillis() - start;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
private static boolean sleep() {
|
||||
if(SystemExiting)
|
||||
return true;
|
||||
|
||||
try {
|
||||
if(ClearDBDebugMode) {
|
||||
Thread.sleep(500);
|
||||
} else {
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return SystemExiting;
|
||||
}
|
||||
|
||||
private static long getMaxMidNeedClean() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(new Date());
|
||||
cal.add(Calendar.YEAR, -3);
|
||||
cal.add(Calendar.DATE, 1);
|
||||
return MessageShardingUtil.getMsgIdFromTimestamp(cal.getTimeInMillis());
|
||||
}
|
||||
|
||||
private static void clearH2DB() {
|
||||
clearOneTable("t_user_messages");
|
||||
if(sleep()) {
|
||||
return;
|
||||
}
|
||||
clearOneTable("t_messages");
|
||||
}
|
||||
|
||||
private static void clearMySQL() {
|
||||
for (int i = 0; i < 128; i++) {
|
||||
clearOneTable("t_user_messages_" + i);
|
||||
if(sleep()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> getCreateSql() {
|
||||
List<String> out = new ArrayList<>();
|
||||
try{
|
||||
BufferedReader br = new BufferedReader(new FileReader("h2/create_table.sql"));//构造一个BufferedReader类来读取文件
|
||||
String s = null;
|
||||
StringBuilder result = new StringBuilder();
|
||||
while((s = br.readLine())!=null) {
|
||||
result.append(s);
|
||||
if (s.contains(";")) {
|
||||
out.add(result.toString());
|
||||
result = new StringBuilder();
|
||||
}
|
||||
}
|
||||
br.close();
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
return out;
|
||||
String msgTableName = MessageShardingUtil.getMessageTable(MessageShardingUtil.getMsgIdFromTimestamp(System.currentTimeMillis()));
|
||||
clearOneTable(msgTableName);
|
||||
}
|
||||
|
||||
private static void clearOneTable(String tableName) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
long mid = getMaxMidNeedClean();
|
||||
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "delete from " + tableName + " where _mid <= " + mid;
|
||||
statement = connection.prepareStatement(sql);
|
||||
int count = statement.executeUpdate();
|
||||
LOG.info("Delete history message {} rows", count);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
//从数据源中获取数据库的连接
|
||||
public static Connection getConnection() throws SQLException {
|
||||
long threadId = Thread.currentThread().getId();
|
||||
}
|
||||
|
||||
if (map.get(threadId) != null) {
|
||||
LOG.error("error here!!!! DB connection not close correctly");
|
||||
}
|
||||
map.put(threadId, Thread.currentThread().getStackTrace().toString());
|
||||
Connection connection = transactionConnection.get();
|
||||
if (connection != null) {
|
||||
LOG.debug("Thread {} get db connection {}", threadId, connection);
|
||||
return connection;
|
||||
private static List<String> getCreateSql() {
|
||||
List<String> out = new ArrayList<>();
|
||||
try{
|
||||
BufferedReader br = new BufferedReader(new FileReader("h2/create_table.sql"));//构造一个BufferedReader类来读取文件
|
||||
String s = null;
|
||||
StringBuilder result = new StringBuilder();
|
||||
while((s = br.readLine())!=null) {
|
||||
result.append(s);
|
||||
if (s.contains(";")) {
|
||||
out.add(result.toString());
|
||||
result = new StringBuilder();
|
||||
}
|
||||
}
|
||||
br.close();
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
//从数据源中获取数据库的连接
|
||||
public static Connection getConnection() throws SQLException {
|
||||
long threadId = Thread.currentThread().getId();
|
||||
|
||||
connection = comboPooledDataSource.getConnection();
|
||||
if (map.get(threadId) != null) {
|
||||
LOG.error("error here!!!! DB connection not close correctly");
|
||||
}
|
||||
map.put(threadId, Thread.currentThread().getStackTrace().toString());
|
||||
Connection connection = transactionConnection.get();
|
||||
if (connection != null) {
|
||||
LOG.debug("Thread {} get db connection {}", threadId, connection);
|
||||
return connection;
|
||||
}
|
||||
|
||||
public static void beginTransaction() {
|
||||
try {
|
||||
Connection connection = getConnection();
|
||||
connection.setAutoCommit(false);
|
||||
transactionConnection.set(connection);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
connection = comboPooledDataSource.getConnection();
|
||||
LOG.debug("Thread {} get db connection {}", threadId, connection);
|
||||
return connection;
|
||||
}
|
||||
|
||||
public static void beginTransaction() {
|
||||
try {
|
||||
Connection connection = getConnection();
|
||||
connection.setAutoCommit(false);
|
||||
transactionConnection.set(connection);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void commit() {
|
||||
try {
|
||||
@@ -180,57 +292,57 @@ public class DBUtil {
|
||||
}
|
||||
}
|
||||
|
||||
//释放资源,将数据库连接还给数据库连接池
|
||||
public static void closeDB(Connection conn,PreparedStatement ps,ResultSet rs) {
|
||||
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
|
||||
try {
|
||||
if (rs!=null) {
|
||||
rs.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (ps!=null) {
|
||||
ps.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (conn!=null && transactionConnection.get() != conn) {
|
||||
conn.close();
|
||||
map.remove(Thread.currentThread().getId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
//释放资源,将数据库连接还给数据库连接池
|
||||
public static void closeDB(Connection conn,PreparedStatement ps,ResultSet rs) {
|
||||
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
|
||||
try {
|
||||
if (rs!=null) {
|
||||
rs.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
//释放资源,将数据库连接还给数据库连接池
|
||||
public static void closeDB(Connection conn, PreparedStatement ps) {
|
||||
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
|
||||
try {
|
||||
if (ps!=null) {
|
||||
ps.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (conn!=null && transactionConnection.get() != conn) {
|
||||
conn.close();
|
||||
map.remove(Thread.currentThread().getId());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
try {
|
||||
if (ps!=null) {
|
||||
ps.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (conn!=null && transactionConnection.get() != conn) {
|
||||
conn.close();
|
||||
map.remove(Thread.currentThread().getId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
}
|
||||
//释放资源,将数据库连接还给数据库连接池
|
||||
public static void closeDB(Connection conn, PreparedStatement ps) {
|
||||
LOG.debug("Thread {} release db connection {}", Thread.currentThread().getId(), conn);
|
||||
try {
|
||||
if (ps!=null) {
|
||||
ps.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (conn!=null && transactionConnection.get() != conn) {
|
||||
conn.close();
|
||||
map.remove(Thread.currentThread().getId());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,19 @@ public class HttpUtils {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HttpUtils.class);
|
||||
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
|
||||
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){
|
||||
LOG.info("POST to {} with data {}", url, jsonStr);
|
||||
public static void httpJsonPost(final String url, final String 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)) {
|
||||
LOG.error("http post failure with empty url");
|
||||
return;
|
||||
@@ -48,12 +58,27 @@ public class HttpUtils {
|
||||
public void onFailure(Call call, IOException e) {
|
||||
e.printStackTrace();
|
||||
LOG.info("POST to {} with data {} failure", url, jsonStr);
|
||||
if(httpCallback != null) {
|
||||
httpCallback.onFailure(-1, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
LOG.info("POST to {} success with response: {}", url, response.body());
|
||||
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) {
|
||||
response.body().close();
|
||||
}
|
||||
|
||||
@@ -12,9 +12,12 @@ public interface IMTopic {
|
||||
String SendMessageTopic = "MS";
|
||||
String MultiCastMessageTopic = "MMC";
|
||||
String RecallMessageTopic = "MR";
|
||||
String RecallMultiCastMessageTopic = "MRMC";
|
||||
String PullMessageTopic = "MP";
|
||||
String NotifyMessageTopic = "MN";
|
||||
String NotifyRecallMessageTopic = "RMN";
|
||||
String NotifyOffline = "ROFL";
|
||||
|
||||
String BroadcastMessageTopic = "MBC";
|
||||
|
||||
String GetUserSettingTopic = "UG";
|
||||
@@ -28,6 +31,7 @@ public interface IMTopic {
|
||||
String DismissGroupTopic = "GD";
|
||||
String ModifyGroupInfoTopic = "GMI";
|
||||
String ModifyGroupAliasTopic = "GMA";
|
||||
String ModifyGroupMemberAliasTopic = "GMMA";
|
||||
String GetGroupInfoTopic = "GPGI";
|
||||
String GetGroupMemberTopic = "GPGM";
|
||||
String TransferGroupTopic = "GTG";
|
||||
|
||||
@@ -10,10 +10,12 @@ package win.liyufan.im;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MessageShardingUtil {
|
||||
private static SpinLock mLock = new SpinLock();
|
||||
private static int rotateId = 0;
|
||||
private static volatile int rotateId = 0;
|
||||
private static volatile long timeId = 0;
|
||||
private static int nodeId = 0;
|
||||
|
||||
private static int rotateIdWidth = 15;
|
||||
@@ -33,19 +35,50 @@ public class MessageShardingUtil {
|
||||
* 所以时间限制是到2157/5/15(2的42次幂代表的时间 + (2018-1970))。节点数限制是小于64,每台服务器每毫秒最多发送32768条消息
|
||||
* @return
|
||||
*/
|
||||
public static long generateId() {
|
||||
public static long generateId() throws Exception {
|
||||
mLock.lock();
|
||||
rotateId = (rotateId + 1)&rotateIdMask;
|
||||
mLock.unLock();
|
||||
|
||||
rotateId = (rotateId + 1)&rotateIdMask;
|
||||
long id = System.currentTimeMillis() - T201801010000;
|
||||
|
||||
if (id > timeId) {
|
||||
timeId = id;
|
||||
rotateId = 1;
|
||||
} else if(id == timeId) {
|
||||
if (rotateId == (rotateIdMask - 1)) { //当前空间已经用完,等待下一个空间打开
|
||||
while (id <= timeId) {
|
||||
id = System.currentTimeMillis() - T201801010000;
|
||||
}
|
||||
mLock.unLock();
|
||||
return generateId();
|
||||
}
|
||||
} else { //id < timeId;
|
||||
if (rotateId > (rotateIdMask -1)*9/10) { //空间已经接近用完
|
||||
if (timeId - id < 3000) { //时间回拨小于3秒,等待时间赶上回拨之前记录
|
||||
while (id < timeId) {
|
||||
id = System.currentTimeMillis() - T201801010000;
|
||||
}
|
||||
mLock.unLock();
|
||||
return generateId();
|
||||
} else { //时间回拨大于3秒,抛出异常,这段时间消息将不可用。
|
||||
mLock.unLock();
|
||||
throw new Exception("Time turn back " + (timeId - id) + " ms, it too long!!!");
|
||||
}
|
||||
} else {
|
||||
id = timeId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
id <<= nodeIdWidth;
|
||||
id += (nodeId & nodeIdMask);
|
||||
|
||||
id <<= rotateIdWidth;
|
||||
id += rotateId;
|
||||
|
||||
mLock.unLock();
|
||||
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -55,7 +88,7 @@ public class MessageShardingUtil {
|
||||
}
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (mid != Long.MAX_VALUE) {
|
||||
if (mid != Long.MAX_VALUE && mid != 0) {
|
||||
mid >>= (nodeIdWidth + rotateIdWidth);
|
||||
Date date = new Date(mid + T201801010000);
|
||||
calendar.setTime(date);
|
||||
@@ -68,8 +101,32 @@ public class MessageShardingUtil {
|
||||
year %= 3;
|
||||
return "t_messages_" + (year * 12 + month);
|
||||
}
|
||||
static Calendar getCalendarFromMessageId(long mid) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (mid != Long.MAX_VALUE && mid != 0) {
|
||||
mid >>= (nodeIdWidth + rotateIdWidth);
|
||||
Date date = new Date(mid + T201801010000);
|
||||
calendar.setTime(date);
|
||||
} else {
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
calendar.setTime(date);
|
||||
}
|
||||
return calendar;
|
||||
}
|
||||
public static long getMsgIdFromTimestamp(long timestamp) {
|
||||
long id = timestamp - T201801010000;
|
||||
|
||||
id <<= rotateIdWidth;
|
||||
id <<= nodeIdWidth;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public static String getPreviousMessageTable(long mid) {
|
||||
return getMessageTable(mid, -1);
|
||||
}
|
||||
|
||||
public static String getMessageTable(long mid, int offset) {
|
||||
if (DBUtil.IsEmbedDB) {
|
||||
return null;
|
||||
}
|
||||
@@ -81,11 +138,40 @@ public class MessageShardingUtil {
|
||||
int month = calendar.get(Calendar.MONTH);
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
year %= 3;
|
||||
month = month - 1;
|
||||
if (month == -1) {
|
||||
month = 11;
|
||||
|
||||
month = month + offset;
|
||||
while (month < 0) {
|
||||
month += 12;
|
||||
year = (year + 3 - 1)%3;
|
||||
}
|
||||
while (month >= 12) {
|
||||
month -= 12;
|
||||
year = (year + 1)%3;
|
||||
}
|
||||
|
||||
return "t_messages_" + (year * 12 + month);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ConcurrentHashMap<Long, Integer> messageIds = new ConcurrentHashMap<>();
|
||||
|
||||
int threadCount = 1000;
|
||||
int loop = 1000000;
|
||||
for (int i = 0; i < threadCount; i++) {
|
||||
new Thread(()->{
|
||||
for (int j = 0; j < loop; j++) {
|
||||
try {
|
||||
long mid = generateId();
|
||||
if(messageIds.put(mid, j) != null) {
|
||||
System.out.println("Duplicated message id !!!!!!" + mid);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
Thread.sleep(1000 * 60 * 10);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user