Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
548d1214f1 | |||
766004fa0a | |||
4fd53fe434 | |||
92c009cde6 | |||
e7076d22de | |||
c47051476b | |||
7f962319f5 | |||
0998501c93 | |||
df343d2731 | |||
22ab521876 | |||
39db13d8de | |||
621c205b6c |
@ -10,15 +10,28 @@
|
|||||||
<listener value="com.zchd.base.AppListener"/>
|
<listener value="com.zchd.base.AppListener"/>
|
||||||
<listener value="net.tccn.ZhubListener"/>
|
<listener value="net.tccn.ZhubListener"/>
|
||||||
|
|
||||||
<source name="int_cache" value="org.redkalex.cache.redis.MyRedisCacheSource">
|
<!-- single -->
|
||||||
<node addr="47.106.237.198" password="hello123!" port="6064" db="0"/>
|
<source name="redis" value="com.zchd.base.RedissionCacheSourcex" password="hello#123!">
|
||||||
|
<node addr="redis://47.106.237.198:6379" db="6"/>
|
||||||
</source>
|
</source>
|
||||||
<source name="str_cache" value="org.redkalex.cache.redis.MyRedisCacheSource">
|
|
||||||
<node addr="47.106.237.198" password="hello123!" port="6064" db="0"/>
|
<!-- cluster -->
|
||||||
|
<!--
|
||||||
|
<source name="redis" value="com.zchd.base.RedissionCacheSourcex" type="cluster">
|
||||||
|
<node addr="redis://127.0.0.1:7000"/>
|
||||||
|
<node addr="redis://127.0.0.1:7001"/>
|
||||||
|
<node addr="redis://127.0.0.1:7002"/>
|
||||||
</source>
|
</source>
|
||||||
<source name="long_cache" value="org.redkalex.cache.redis.MyRedisCacheSource">
|
-->
|
||||||
<node addr="47.106.237.198" password="hello123!" port="6064" db="0"/>
|
|
||||||
|
<!-- sentinel -->
|
||||||
|
<!--
|
||||||
|
<source name="redis" value="com.zchd.base.RedissionCacheSourcex" type="sentinel" master="mymaster">
|
||||||
|
<node addr="redis://127.0.0.1:26379"/>
|
||||||
|
<node addr="redis://127.0.0.1:26380"/>
|
||||||
|
<node addr="redis://127.0.0.1:26381"/>
|
||||||
</source>
|
</source>
|
||||||
|
-->
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
<server protocol="HTTP" port="8091" maxbody="2m">
|
<server protocol="HTTP" port="8091" maxbody="2m">
|
||||||
|
@ -6,7 +6,9 @@ javax.level=INFO
|
|||||||
com.sun.level=INFO
|
com.sun.level=INFO
|
||||||
sun.level=INFO
|
sun.level=INFO
|
||||||
jdk.level=INFO
|
jdk.level=INFO
|
||||||
java.util.logging.FileHandler.level=FINE
|
io.netty.level = INFO
|
||||||
|
org.postgresql.level = INFO
|
||||||
|
java.util.logging.FileHandler.level=INFO
|
||||||
#10M
|
#10M
|
||||||
java.util.logging.FileHandler.limit=10485760
|
java.util.logging.FileHandler.limit=10485760
|
||||||
java.util.logging.FileHandler.count=10000
|
java.util.logging.FileHandler.count=10000
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
<persistence-unit name="z_im">
|
<persistence-unit name="z_im">
|
||||||
<shared-cache-mode>ALL</shared-cache-mode>
|
<shared-cache-mode>ALL</shared-cache-mode>
|
||||||
<properties>
|
<properties>
|
||||||
|
<!-- mysql -->
|
||||||
|
<!--<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://47.106.237.198:3306/z_im?currentSchema=public"/>-->
|
||||||
|
<!-- postgresql -->
|
||||||
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://47.106.237.198:3306/z_im"/>
|
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://47.106.237.198:3306/z_im"/>
|
||||||
<property name="javax.persistence.jdbc.user" value="u_im"/>
|
<property name="javax.persistence.jdbc.user" value="u_im"/>
|
||||||
<property name="javax.persistence.jdbc.password" value="u_im@2024"/>
|
<property name="javax.persistence.jdbc.password" value="u_im@2024"/>
|
||||||
|
83
docs/z_im-mysql.sql
Normal file
83
docs/z_im-mysql.sql
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
CREATE TABLE `appinfo` (
|
||||||
|
`appid` varchar(64) NOT NULL DEFAULT '' COMMENT '[平台标识]',
|
||||||
|
`appname` varchar(64) NOT NULL DEFAULT '' COMMENT '[平台名称]',
|
||||||
|
`appsecret` varchar(64) NOT NULL DEFAULT '' COMMENT '[校验码]',
|
||||||
|
`createtime` bigint NOT NULL DEFAULT '0' COMMENT '[创建时间]',
|
||||||
|
`updatetime` bigint NOT NULL DEFAULT '0' COMMENT '[修改时间]',
|
||||||
|
`status` smallint NOT NULL DEFAULT '10' COMMENT '[状态]10正常, 40停用,80删除',
|
||||||
|
`checkfriend` smallint NOT NULL DEFAULT '0' COMMENT '[是否检查好友关系,1是,0否]',
|
||||||
|
`checkblack` smallint NOT NULL DEFAULT '0' COMMENT '[是否检查拉黑关系,1是,0否]',
|
||||||
|
`machineretract` smallint NOT NULL DEFAULT '0' COMMENT '[是否需要机审撤回处理,1是,0否]',
|
||||||
|
`hasnext` smallint NOT NULL DEFAULT '0' COMMENT '[是否有下一步流程,1是,0否]',
|
||||||
|
PRIMARY KEY (`appid`)
|
||||||
|
) ENGINE=InnoDB COMMENT='平台信息表';
|
||||||
|
|
||||||
|
CREATE TABLE `channelmessage` (
|
||||||
|
`messageid` varchar(64) NOT NULL DEFAULT '' COMMENT '[消息ID]',
|
||||||
|
`content` text NOT NULL COMMENT '[消息内容]',
|
||||||
|
`appid` varchar(8) NOT NULL DEFAULT '' COMMENT '[平台ID]',
|
||||||
|
`channeltype` varchar(15) NOT NULL DEFAULT '' COMMENT '[平台频道类型]',
|
||||||
|
`channelvalue` varchar(64) NOT NULL DEFAULT '' COMMENT '[平台频道ID]',
|
||||||
|
`senduserid` int NOT NULL DEFAULT '0' COMMENT '[发送人]',
|
||||||
|
`createtime` bigint NOT NULL DEFAULT '0' COMMENT '[创建时间]',
|
||||||
|
`status` smallint NOT NULL DEFAULT '10' COMMENT '[状态]80删除',
|
||||||
|
`type` varchar(255) NOT NULL DEFAULT '' COMMENT '[消息类型]',
|
||||||
|
`title` varchar(255) NOT NULL DEFAULT '' COMMENT '[消息标题]',
|
||||||
|
`attachment` varchar(2048) NOT NULL DEFAULT '' COMMENT '[消息附加信息]',
|
||||||
|
PRIMARY KEY (`messageid`) USING BTREE
|
||||||
|
) ENGINE=InnoDB COMMENT='频道内容表';
|
||||||
|
|
||||||
|
CREATE TABLE `channeluser` (
|
||||||
|
`cuid` varchar(64) NOT NULL DEFAULT '' COMMENT '[用户组ID]',
|
||||||
|
`appid` varchar(64) NOT NULL DEFAULT '' COMMENT '[平台ID]',
|
||||||
|
`channeltype` varchar(15) NOT NULL DEFAULT '' COMMENT '[平台频道类型]',
|
||||||
|
`channelvalue` varchar(64) NOT NULL DEFAULT '' COMMENT '[平台频道ID]',
|
||||||
|
`userid` int NOT NULL DEFAULT '0' COMMENT '[订阅用户]',
|
||||||
|
`createtime` bigint NOT NULL DEFAULT '0' COMMENT '[创建时间]',
|
||||||
|
`lastaccepttime` bigint NOT NULL DEFAULT '0' COMMENT '[最后接收时间]',
|
||||||
|
`status` smallint NOT NULL DEFAULT '10' COMMENT '[状态]10正常,42禁言',
|
||||||
|
`identitytype` smallint NOT NULL DEFAULT '10' COMMENT '[用户身份,0游客,10成员,20管理员,30群主]',
|
||||||
|
PRIMARY KEY (`cuid`)
|
||||||
|
) ENGINE=InnoDB COMMENT='用户组信息表';
|
||||||
|
|
||||||
|
CREATE TABLE `friendmessage` (
|
||||||
|
`messageid` varchar(64) NOT NULL DEFAULT '' COMMENT '[私聊ID]发送人-时间戳',
|
||||||
|
`messagetype` varchar(32) NOT NULL DEFAULT '' COMMENT '[消息类型]',
|
||||||
|
`content` text NOT NULL COMMENT '[私聊内容]',
|
||||||
|
`senduserid` int NOT NULL DEFAULT '0' COMMENT '[发送人]',
|
||||||
|
`receiveuserid` int NOT NULL DEFAULT '0' COMMENT '[接收人]',
|
||||||
|
`createtime` bigint NOT NULL DEFAULT '0' COMMENT '[创建时间]',
|
||||||
|
`status` smallint NOT NULL DEFAULT '20' COMMENT '[状态]10已发送,20未发送,21仅在线发送',
|
||||||
|
`type` varchar(255) NOT NULL DEFAULT '' COMMENT '[消息类型]',
|
||||||
|
`title` varchar(255) NOT NULL DEFAULT '' COMMENT '[消息标题]',
|
||||||
|
`attachment` varchar(2048) NOT NULL DEFAULT '' COMMENT '[消息附加信息]',
|
||||||
|
傻 `newField` varchar(255) NOT NULL DEFAULT '' COMMENT '[新字段描述]',
|
||||||
|
PRIMARY KEY (`messageid`)
|
||||||
|
) ENGINE=InnoDB COMMENT='私聊内容表';
|
||||||
|
|
||||||
|
CREATE TABLE `imuser` (
|
||||||
|
`userid` int NOT NULL COMMENT '[用户标识]',
|
||||||
|
`guserid` varchar(64) NOT NULL DEFAULT '' COMMENT '[平台自用用户标识]',
|
||||||
|
`appid` varchar(8) NOT NULL DEFAULT '' COMMENT '[关联平台标识]',
|
||||||
|
`gender` smallint NOT NULL DEFAULT '0' COMMENT '[性别]',
|
||||||
|
`nickname` varchar(32) NOT NULL DEFAULT '' COMMENT '[昵称]',
|
||||||
|
`face` varchar(128) NOT NULL DEFAULT '' COMMENT '[头像]',
|
||||||
|
`createtime` bigint NOT NULL DEFAULT '0' COMMENT '[创建时间]',
|
||||||
|
`imtoken` varchar(125) DEFAULT '' COMMENT '[用户认证]',
|
||||||
|
`updatetime` bigint NOT NULL DEFAULT '0' COMMENT '[修改时间]',
|
||||||
|
`lastaccepttime` bigint NOT NULL DEFAULT '0' COMMENT '[接收时间]',
|
||||||
|
`status` smallint NOT NULL DEFAULT '10' COMMENT '[状态]10正常,40停用,80删除',
|
||||||
|
PRIMARY KEY (`userid`)
|
||||||
|
) ENGINE=InnoDB COMMENT='IM用户';
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
INSERT INTO z_im.appinfo (appid, appname, appsecret, createtime, updatetime, status, checkfriend, checkblack, machineretract, hasnext) VALUES
|
||||||
|
('krlq2lp4', '应用A-开发服', '108319232efb4880bcb4f3323829692c', 0, 0, 10, 0, 0, 0, 0),
|
||||||
|
('xrkqglth', '应用A-测试服', '108319232efb4880bcb4f3323829692d', 0, 0, 10, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
INSERT INTO imuser (userid, guserid, appid, gender, nickname, face, createtime, imtoken, updatetime, lastaccepttime, status) VALUES
|
||||||
|
(10001, '1784509137732849665', 'xrkqglth', 0, '', '', 1721373487374, 'c75ab6feda394d8c8b28371cda45ec12', 1748780429, 1748780429, 10),
|
||||||
|
(10002, '1784421470808907778', 'xrkqglth', 0, '', '', 1721377122233, '69ca1dcbebc645b78f84a9e88287382d', 1748780432, 1748780432, 10);
|
||||||
|
|
136
docs/z_im-postgresql.sql
Normal file
136
docs/z_im-postgresql.sql
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
CREATE TABLE appinfo (
|
||||||
|
appid VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
appname VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
appsecret VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
createtime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
updatetime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
status SMALLINT NOT NULL DEFAULT 10,
|
||||||
|
checkfriend SMALLINT NOT NULL DEFAULT 0,
|
||||||
|
checkblack SMALLINT NOT NULL DEFAULT 0,
|
||||||
|
machineretract SMALLINT NOT NULL DEFAULT 0,
|
||||||
|
hasnext SMALLINT NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (appid)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE appinfo IS '平台信息表';
|
||||||
|
COMMENT ON COLUMN appinfo.appid IS '[平台标识]';
|
||||||
|
COMMENT ON COLUMN appinfo.appname IS '[平台名称]';
|
||||||
|
COMMENT ON COLUMN appinfo.appsecret IS '[校验码]';
|
||||||
|
COMMENT ON COLUMN appinfo.createtime IS '[创建时间]';
|
||||||
|
COMMENT ON COLUMN appinfo.updatetime IS '[修改时间]';
|
||||||
|
COMMENT ON COLUMN appinfo.status IS '[状态]10正常, 40停用,80删除';
|
||||||
|
COMMENT ON COLUMN appinfo.checkfriend IS '[是否检查好友关系,1是,0否]';
|
||||||
|
COMMENT ON COLUMN appinfo.checkblack IS '[是否检查拉黑关系,1是,0否]';
|
||||||
|
COMMENT ON COLUMN appinfo.machineretract IS '[是否需要机审撤回处理,1是,0否]';
|
||||||
|
COMMENT ON COLUMN appinfo.hasnext IS '[是否有下一步流程,1是,0否]';
|
||||||
|
|
||||||
|
CREATE TABLE channelmessage (
|
||||||
|
messageid VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
appid VARCHAR(8) NOT NULL DEFAULT '',
|
||||||
|
channeltype VARCHAR(15) NOT NULL DEFAULT '',
|
||||||
|
channelvalue VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
senduserid INT NOT NULL DEFAULT 0,
|
||||||
|
createtime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
status SMALLINT NOT NULL DEFAULT 10,
|
||||||
|
type VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
|
title VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
|
attachment VARCHAR(2048) NOT NULL DEFAULT '',
|
||||||
|
PRIMARY KEY (messageid)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE channelmessage IS '频道内容表';
|
||||||
|
COMMENT ON COLUMN channelmessage.messageid IS '[消息ID]';
|
||||||
|
COMMENT ON COLUMN channelmessage.content IS '[消息内容]';
|
||||||
|
COMMENT ON COLUMN channelmessage.appid IS '[平台ID]';
|
||||||
|
COMMENT ON COLUMN channelmessage.channeltype IS '[平台频道类型]';
|
||||||
|
COMMENT ON COLUMN channelmessage.channelvalue IS '[平台频道ID]';
|
||||||
|
COMMENT ON COLUMN channelmessage.senduserid IS '[发送人]';
|
||||||
|
COMMENT ON COLUMN channelmessage.createtime IS '[创建时间]';
|
||||||
|
COMMENT ON COLUMN channelmessage.status IS '[状态]80删除';
|
||||||
|
COMMENT ON COLUMN channelmessage.type IS '[消息类型]';
|
||||||
|
COMMENT ON COLUMN channelmessage.title IS '[消息标题]';
|
||||||
|
COMMENT ON COLUMN channelmessage.attachment IS '[消息附加信息]';
|
||||||
|
|
||||||
|
CREATE TABLE channeluser (
|
||||||
|
cuid VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
appid VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
channeltype VARCHAR(15) NOT NULL DEFAULT '',
|
||||||
|
channelvalue VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
userid INT NOT NULL DEFAULT 0,
|
||||||
|
createtime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
lastaccepttime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
status SMALLINT NOT NULL DEFAULT 10,
|
||||||
|
identitytype SMALLINT NOT NULL DEFAULT 10,
|
||||||
|
PRIMARY KEY (cuid)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE channeluser IS '用户组信息表';
|
||||||
|
COMMENT ON COLUMN channeluser.cuid IS '[用户组ID]';
|
||||||
|
COMMENT ON COLUMN channeluser.appid IS '[平台ID]';
|
||||||
|
COMMENT ON COLUMN channeluser.channeltype IS '[平台频道类型]';
|
||||||
|
COMMENT ON COLUMN channeluser.channelvalue IS '[平台频道ID]';
|
||||||
|
COMMENT ON COLUMN channeluser.userid IS '[订阅用户]';
|
||||||
|
COMMENT ON COLUMN channeluser.createtime IS '[创建时间]';
|
||||||
|
COMMENT ON COLUMN channeluser.lastaccepttime IS '[最后接收时间]';
|
||||||
|
COMMENT ON COLUMN channeluser.status IS '[状态]10正常,42禁言';
|
||||||
|
COMMENT ON COLUMN channeluser.identitytype IS '[用户身份,0游客,10成员,20管理员,30群主]';
|
||||||
|
|
||||||
|
CREATE TABLE friendmessage (
|
||||||
|
messageid VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
messagetype VARCHAR(32) NOT NULL DEFAULT '',
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
senduserid INT NOT NULL DEFAULT 0,
|
||||||
|
receiveuserid INT NOT NULL DEFAULT 0,
|
||||||
|
createtime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
status SMALLINT NOT NULL DEFAULT 20,
|
||||||
|
type VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
|
title VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
|
attachment VARCHAR(2048) NOT NULL DEFAULT '',
|
||||||
|
PRIMARY KEY (messageid)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE friendmessage IS '私聊内容表';
|
||||||
|
COMMENT ON COLUMN friendmessage.messageid IS '[私聊ID]发送人-时间戳';
|
||||||
|
COMMENT ON COLUMN friendmessage.messagetype IS '[消息类型]';
|
||||||
|
COMMENT ON COLUMN friendmessage.content IS '[私聊内容]';
|
||||||
|
COMMENT ON COLUMN friendmessage.senduserid IS '[发送人]';
|
||||||
|
COMMENT ON COLUMN friendmessage.receiveuserid IS '[接收人]';
|
||||||
|
COMMENT ON COLUMN friendmessage.createtime IS '[创建时间]';
|
||||||
|
COMMENT ON COLUMN friendmessage.status IS '[状态]10已发送,20未发送,21仅在线发送';
|
||||||
|
COMMENT ON COLUMN friendmessage.type IS '[消息类型]';
|
||||||
|
COMMENT ON COLUMN friendmessage.title IS '[消息标题]';
|
||||||
|
COMMENT ON COLUMN friendmessage.attachment IS '[消息附加信息]';
|
||||||
|
|
||||||
|
CREATE TABLE imuser (
|
||||||
|
userid INT NOT NULL,
|
||||||
|
guserid VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
|
appid VARCHAR(8) NOT NULL DEFAULT '',
|
||||||
|
gender SMALLINT NOT NULL DEFAULT 0,
|
||||||
|
nickname VARCHAR(32) NOT NULL DEFAULT '',
|
||||||
|
face VARCHAR(128) NOT NULL DEFAULT '',
|
||||||
|
createtime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
imtoken VARCHAR(125) DEFAULT '',
|
||||||
|
updatetime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
lastaccepttime BIGINT NOT NULL DEFAULT 0,
|
||||||
|
status SMALLINT NOT NULL DEFAULT 10,
|
||||||
|
PRIMARY KEY (userid)
|
||||||
|
);
|
||||||
|
COMMENT ON TABLE imuser IS 'IM用户';
|
||||||
|
COMMENT ON COLUMN imuser.userid IS '[用户标识]';
|
||||||
|
COMMENT ON COLUMN imuser.guserid IS '[平台自用用户标识]';
|
||||||
|
COMMENT ON COLUMN imuser.appid IS '[关联平台标识]';
|
||||||
|
COMMENT ON COLUMN imuser.gender IS '[性别]';
|
||||||
|
COMMENT ON COLUMN imuser.nickname IS '[昵称]';
|
||||||
|
COMMENT ON COLUMN imuser.face IS '[头像]';
|
||||||
|
COMMENT ON COLUMN imuser.createtime IS '[创建时间]';
|
||||||
|
COMMENT ON COLUMN imuser.imtoken IS '[用户认证]';
|
||||||
|
COMMENT ON COLUMN imuser.updatetime IS '[修改时间]';
|
||||||
|
COMMENT ON COLUMN imuser.lastaccepttime IS '[接收时间]';
|
||||||
|
COMMENT ON COLUMN imuser.status IS '[状态]10正常,40停用,80删除';
|
||||||
|
|
||||||
|
--
|
||||||
|
INSERT INTO z_im.appinfo (appid, appname, appsecret, createtime, updatetime, status, checkfriend, checkblack, machineretract, hasnext) VALUES
|
||||||
|
('krlq2lp4', '应用A-开发服', '108319232efb4880bcb4f3323829692c', 0, 0, 10, 0, 0, 0, 0),
|
||||||
|
('xrkqglth', '应用A-测试服', '108319232efb4880bcb4f3323829692d', 0, 0, 10, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
INSERT INTO imuser (userid, guserid, appid, gender, nickname, face, createtime, imtoken, updatetime, lastaccepttime, status) VALUES
|
||||||
|
(10001, '1784509137732849665', 'xrkqglth', 0, '', '', 1721373487374, 'c75ab6feda394d8c8b28371cda45ec12', 1748780429, 1748780429, 10),
|
||||||
|
(10002, '1784421470808907778', 'xrkqglth', 0, '', '', 1721377122233, '69ca1dcbebc645b78f84a9e88287382d', 1748780432, 1748780432, 10);
|
||||||
|
|
27
pom.xml
27
pom.xml
@ -14,6 +14,7 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
<!-- https://nexus.1216.top/repo/ -->
|
||||||
<repository>
|
<repository>
|
||||||
<id>maven-release</id>
|
<id>maven-release</id>
|
||||||
<name>maven-nexus</name>
|
<name>maven-nexus</name>
|
||||||
@ -25,19 +26,43 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.redkale</groupId>
|
<groupId>org.redkale</groupId>
|
||||||
<artifactId>redkale</artifactId>
|
<artifactId>redkale</artifactId>
|
||||||
|
<version>2.2.250620</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.redkalex</groupId>
|
||||||
|
<artifactId>redkale-plugins</artifactId>
|
||||||
<version>2.2.0</version>
|
<version>2.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.redisson</groupId>
|
||||||
|
<artifactId>redisson</artifactId>
|
||||||
|
<version>3.47.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-j</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
<version>8.2.0</version>
|
<version>9.3.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.7.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.tccn</groupId>
|
<groupId>net.tccn</groupId>
|
||||||
<artifactId>zhub-client-redkale</artifactId>
|
<artifactId>zhub-client-redkale</artifactId>
|
||||||
<version>x.22.0</version>
|
<version>x.22.0</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>redkale</artifactId>
|
||||||
|
<groupId>org.redkale</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--<dependency>
|
<!--<dependency>
|
||||||
|
@ -5,8 +5,8 @@ import org.redkale.convert.json.JsonConvert;
|
|||||||
import org.redkale.service.AbstractService;
|
import org.redkale.service.AbstractService;
|
||||||
import org.redkale.service.RetResult;
|
import org.redkale.service.RetResult;
|
||||||
import org.redkale.source.DataSource;
|
import org.redkale.source.DataSource;
|
||||||
|
import org.redkale.util.AnyValue;
|
||||||
import org.redkale.util.Sheet;
|
import org.redkale.util.Sheet;
|
||||||
import org.redkalex.cache.redis.MyRedisCacheSource;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -24,14 +24,13 @@ public class BaseService extends AbstractService {
|
|||||||
@Resource(name = "zhub")
|
@Resource(name = "zhub")
|
||||||
protected ZHubClient zhub;
|
protected ZHubClient zhub;
|
||||||
|
|
||||||
@Resource(name = "int_cache")
|
/*@Resource(name = "redis")
|
||||||
protected MyRedisCacheSource<Integer> intCache;
|
protected RedissionCacheSourcex<Integer> intCache;
|
||||||
|
|
||||||
@Resource(name = "long_cache")
|
@Resource(name = "redis")
|
||||||
protected MyRedisCacheSource<Long> longCache;
|
protected RedissionCacheSourcex<Long> longCache;*/
|
||||||
|
@Resource(name = "redis")
|
||||||
@Resource(name = "str_cache")
|
protected RedissionCacheSourcex redisCache;
|
||||||
protected MyRedisCacheSource<String> strCache;
|
|
||||||
|
|
||||||
@Resource(name = "z_im")
|
@Resource(name = "z_im")
|
||||||
protected DataSource zimSource;
|
protected DataSource zimSource;
|
||||||
@ -42,6 +41,21 @@ public class BaseService extends AbstractService {
|
|||||||
@Resource(name = "APP_NAME")
|
@Resource(name = "APP_NAME")
|
||||||
protected String APP_NAME = "";
|
protected String APP_NAME = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(AnyValue config) {
|
||||||
|
|
||||||
|
/*PoolSource<Connection> source = ((DataJdbcSource) zimSource).getReadPoolSource();
|
||||||
|
// postgresql 设置当前schema
|
||||||
|
if ("postgresql".equals(source.getDbtype())) {
|
||||||
|
String url = source.getUrl();
|
||||||
|
String schema = getCurrentSchema(url);
|
||||||
|
if (Utils.isEmpty(schema)) {
|
||||||
|
schema = "public";
|
||||||
|
}
|
||||||
|
((DataJdbcSource) zimSource).directExecute(String.format("SET search_path TO %s;", schema));
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
protected RetResult retError(String info) {
|
protected RetResult retError(String info) {
|
||||||
return new RetResult<>(100, info);
|
return new RetResult<>(100, info);
|
||||||
}
|
}
|
||||||
@ -49,4 +63,21 @@ public class BaseService extends AbstractService {
|
|||||||
protected RetResult retError(int code, String info) {
|
protected RetResult retError(int code, String info) {
|
||||||
return new RetResult<>(code, info);
|
return new RetResult<>(code, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 postgresql url当前schema
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
/*protected String getCurrentSchema(String url) {
|
||||||
|
String[] arr = url.split("currentSchema=");
|
||||||
|
if (arr.length > 1) {
|
||||||
|
String[] arr2 = arr[1].split("&");
|
||||||
|
if (arr2.length > 0) {
|
||||||
|
return arr2[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
99
src/com/zchd/base/RedissionCacheSourcex.java
Normal file
99
src/com/zchd/base/RedissionCacheSourcex.java
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package com.zchd.base;
|
||||||
|
|
||||||
|
import org.redisson.Redisson;
|
||||||
|
import org.redisson.config.BaseConfig;
|
||||||
|
import org.redisson.config.Config;
|
||||||
|
import org.redkale.service.Local;
|
||||||
|
import org.redkale.source.CacheSource;
|
||||||
|
import org.redkale.util.AnyValue;
|
||||||
|
import org.redkale.util.AutoLoad;
|
||||||
|
import org.redkale.util.ResourceType;
|
||||||
|
import org.redkalex.cache.RedisCacheSource;
|
||||||
|
import org.redkalex.cache.RedissionCacheSource;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@Local
|
||||||
|
@AutoLoad(false)
|
||||||
|
@ResourceType(CacheSource.class)
|
||||||
|
public class RedissionCacheSourcex<V> extends RedissionCacheSource<V> {
|
||||||
|
|
||||||
|
private final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(AnyValue conf) {
|
||||||
|
if (this.convert == null) this.convert = this.defaultConvert;
|
||||||
|
if (conf == null) conf = new AnyValue.DefaultAnyValue();
|
||||||
|
|
||||||
|
final List<String> addresses = new ArrayList<>();
|
||||||
|
Config config = new Config();
|
||||||
|
AnyValue[] nodes = conf.getAnyValues("node");
|
||||||
|
String type = conf.getOrDefault("type", "");
|
||||||
|
String masterName = conf.getOrDefault("master", "");
|
||||||
|
BaseConfig baseConfig = null;
|
||||||
|
for (AnyValue node : nodes) {
|
||||||
|
String addr = node.getValue("addr");
|
||||||
|
addresses.add(addr);
|
||||||
|
String db0 = node.getValue("db", "").trim();
|
||||||
|
if (!db0.isEmpty()) this.db = Integer.valueOf(db0);
|
||||||
|
if (nodes.length == 1) {
|
||||||
|
baseConfig = config.useSingleServer();
|
||||||
|
config.useSingleServer().setAddress(addr);
|
||||||
|
config.useSingleServer().setDatabase(this.db);
|
||||||
|
} else if ("masterslave".equalsIgnoreCase(type)) { //主从
|
||||||
|
baseConfig = config.useMasterSlaveServers();
|
||||||
|
if (node.get("master") != null) {
|
||||||
|
config.useMasterSlaveServers().setMasterAddress(addr);
|
||||||
|
} else {
|
||||||
|
config.useMasterSlaveServers().addSlaveAddress(addr);
|
||||||
|
}
|
||||||
|
config.useMasterSlaveServers().setDatabase(this.db);
|
||||||
|
} else if ("cluster".equalsIgnoreCase(type)) { //集群
|
||||||
|
baseConfig = config.useClusterServers();
|
||||||
|
config.useClusterServers().addNodeAddress(addr);
|
||||||
|
} else if ("replicated".equalsIgnoreCase(type)) { //
|
||||||
|
baseConfig = config.useReplicatedServers();
|
||||||
|
config.useReplicatedServers().addNodeAddress(addr);
|
||||||
|
config.useReplicatedServers().setDatabase(this.db);
|
||||||
|
} else if ("sentinel".equalsIgnoreCase(type)) { //
|
||||||
|
baseConfig = config.useSentinelServers();
|
||||||
|
config.useSentinelServers().addSentinelAddress(addr);
|
||||||
|
config.useSentinelServers().setDatabase(this.db);
|
||||||
|
config.useSentinelServers().setMasterName(masterName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (baseConfig != null) {
|
||||||
|
String username = conf.getValue("username", "").trim();
|
||||||
|
String password = conf.getValue("password", "").trim();
|
||||||
|
String retryAttempts = conf.getValue("retryAttempts", "").trim();
|
||||||
|
String retryInterval = conf.getValue("retryInterval", "").trim();
|
||||||
|
if (!username.isEmpty()) baseConfig.setUsername(username);
|
||||||
|
if (!password.isEmpty()) baseConfig.setPassword(password);
|
||||||
|
if (!retryAttempts.isEmpty()) baseConfig.setRetryAttempts(Integer.parseInt(retryAttempts));
|
||||||
|
if (!retryInterval.isEmpty()) baseConfig.setRetryInterval(Integer.parseInt(retryInterval));
|
||||||
|
}
|
||||||
|
this.redisson = Redisson.create(config);
|
||||||
|
this.nodeAddrs = addresses;
|
||||||
|
if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, RedisCacheSource.class.getSimpleName() + ": addrs=" + addresses + ", db=" + db);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBit(String key, int offset) {
|
||||||
|
return redisson.getBitSet(key).get(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBit(String key, int offset, boolean bool) {
|
||||||
|
redisson.getBitSet(key).set(offset, bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Object> V getHm(String key, T field) {
|
||||||
|
return (V) redisson.getMap(key).get(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hset(String key, String field, Object value) {
|
||||||
|
hset(key, field, value.getClass(), value);
|
||||||
|
}
|
||||||
|
}
|
@ -9,16 +9,17 @@ import com.zchd.zim.entity.ChannelUser;
|
|||||||
import com.zchd.zim.entity.ImUser;
|
import com.zchd.zim.entity.ImUser;
|
||||||
import net.tccn.zhub.Lock;
|
import net.tccn.zhub.Lock;
|
||||||
import net.tccn.zhub.RpcResult;
|
import net.tccn.zhub.RpcResult;
|
||||||
import org.redkale.convert.json.JsonConvert;
|
|
||||||
import org.redkale.net.http.RestMapping;
|
import org.redkale.net.http.RestMapping;
|
||||||
import org.redkale.net.http.RestService;
|
import org.redkale.net.http.RestService;
|
||||||
import org.redkale.service.RetResult;
|
import org.redkale.service.RetResult;
|
||||||
import org.redkale.source.*;
|
import org.redkale.source.ColumnValue;
|
||||||
|
import org.redkale.source.FilterBean;
|
||||||
|
import org.redkale.source.FilterNode;
|
||||||
|
import org.redkale.source.Flipper;
|
||||||
import org.redkale.util.AnyValue;
|
import org.redkale.util.AnyValue;
|
||||||
import org.redkale.util.Comment;
|
import org.redkale.util.Comment;
|
||||||
import org.redkale.util.TypeToken;
|
import org.redkale.util.TypeToken;
|
||||||
import org.redkale.util.Utility;
|
import org.redkale.util.Utility;
|
||||||
import org.redkalex.cache.redis.MyRedisCacheSource;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -30,15 +31,16 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
public class ImAccountService extends BaseService {
|
public class ImAccountService extends BaseService {
|
||||||
|
|
||||||
|
|
||||||
@Resource(name = "str_cache")
|
/*@Resource(name = "redis")
|
||||||
protected MyRedisCacheSource<String> strCache;
|
protected RedissionCacheSourcex<String> strCache;*/
|
||||||
@Resource
|
@Resource
|
||||||
protected ImMessageMonitor messageMonitor;
|
protected ImMessageMonitor messageMonitor;
|
||||||
@Resource
|
/*@Resource
|
||||||
protected ImAccountService accountService;
|
protected ImAccountService accountService;*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(AnyValue config) {
|
public void init(AnyValue config) {
|
||||||
|
super.init(config);
|
||||||
|
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
List<Serializable> list = zimSource.queryColumnList("userid", ImUser.class, new Flipper(1, "userid DESC"), (FilterBean) null);
|
List<Serializable> list = zimSource.queryColumnList("userid", ImUser.class, new Flipper(1, "userid DESC"), (FilterBean) null);
|
||||||
@ -46,7 +48,8 @@ public class ImAccountService extends BaseService {
|
|||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
userid = Kv.toAs(list.get(0), int.class);
|
userid = Kv.toAs(list.get(0), int.class);
|
||||||
}
|
}
|
||||||
intCache.set("im:max-userid", userid);
|
// intCache.set("im:max-userid", userid);
|
||||||
|
redisCache.setLongAsync("im:max-userid", userid);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 游戏用户注册
|
// 游戏用户注册
|
||||||
@ -93,10 +96,10 @@ public class ImAccountService extends BaseService {
|
|||||||
SubscribeBean bean = r.getValue();
|
SubscribeBean bean = r.getValue();
|
||||||
String imtoken = bean.getImtoken();
|
String imtoken = bean.getImtoken();
|
||||||
|
|
||||||
ImUser user = accountService.currentImUser(imtoken);
|
ImUser user = currentImUser(imtoken);
|
||||||
int userid = user.getUserid();
|
int userid = user.getUserid();
|
||||||
zimSource.updateColumn(ImUser.class, userid, ColumnValue.create("status", ImUser.STATUS_FREEZE_ACTIVE));
|
zimSource.updateColumn(ImUser.class, userid, ColumnValue.create("status", ImUser.STATUS_FREEZE_ACTIVE));
|
||||||
intCache.setBit("im:banned-talk", userid, true);
|
redisCache.setBit("im:banned-talk", userid, true);
|
||||||
return r.render();
|
return r.render();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -106,10 +109,10 @@ public class ImAccountService extends BaseService {
|
|||||||
SubscribeBean bean = r.getValue();
|
SubscribeBean bean = r.getValue();
|
||||||
String imtoken = bean.getImtoken();
|
String imtoken = bean.getImtoken();
|
||||||
|
|
||||||
ImUser user = accountService.currentImUser(imtoken);
|
ImUser user = currentImUser(imtoken);
|
||||||
int userid = user.getUserid();
|
int userid = user.getUserid();
|
||||||
zimSource.updateColumn(ImUser.class, userid, ColumnValue.create("status", 10));
|
zimSource.updateColumn(ImUser.class, userid, ColumnValue.create("status", 10));
|
||||||
intCache.setBit("im:banned-talk", userid, false);
|
redisCache.setBit("im:banned-talk", userid, false);
|
||||||
return r.render();
|
return r.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -117,16 +120,19 @@ public class ImAccountService extends BaseService {
|
|||||||
|
|
||||||
@Comment("获取当前用户ID")
|
@Comment("获取当前用户ID")
|
||||||
public ImUser currentImUser(String token) {
|
public ImUser currentImUser(String token) {
|
||||||
|
ImUser user = (ImUser) redisCache.hget("im:user-token", token, ImUser.class);
|
||||||
ImUser user = strCache.hget("im:user-token", token, new TypeToken<ImUser>() {
|
|
||||||
}.getType());
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = zimSource.find(ImUser.class, FilterNode.create("imtoken", token));
|
user = zimSource.find(ImUser.class, FilterNode.create("imtoken", token));
|
||||||
strCache.hset("im:user-token", token, JsonConvert.root(), user);
|
// strCache.hset("im:user-token", token, JsonConvert.root(), user);
|
||||||
|
redisCache.hset("im:user-token", token, user);
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImUser getImUser(ImBean bean) {
|
||||||
|
return zimSource.find(ImUser.class, FilterNode.create("guserid", bean.getGuserid()).and("appid", bean.getAppid()));
|
||||||
|
}
|
||||||
|
|
||||||
/*@Comment("获取当前用户ID")
|
/*@Comment("获取当前用户ID")
|
||||||
public int currentImUserId(String token) {
|
public int currentImUserId(String token) {
|
||||||
return currentImUser(token).getUserid();
|
return currentImUser(token).getUserid();
|
||||||
@ -151,17 +157,20 @@ public class ImAccountService extends BaseService {
|
|||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = ImUser.buildImUser(bean.getGuserid(), bean.getAppid());
|
user = ImUser.buildImUser(bean.getGuserid(), bean.getAppid());
|
||||||
int userid = (int) intCache.incr("im:max-userid");
|
int userid = (int) redisCache.incr("im:max-userid");
|
||||||
user.setUserid(userid);
|
user.setUserid(userid);
|
||||||
|
|
||||||
user.setImtoken(Utility.uuid()); // 生成IM-TOKEN
|
user.setImtoken(Utility.uuid()); // 生成IM-TOKEN
|
||||||
zimSource.insert(user);
|
zimSource.insert(user);
|
||||||
|
|
||||||
// intCache.set("im:account-user-token:" + user.getImtoken(), userid);
|
// intCache.set("im:account-user-token:" + user.getImtoken(), userid);
|
||||||
strCache.hset("im:user-token", user.getImtoken(), JsonConvert.root(), user);
|
} else {
|
||||||
|
user.setImtoken(Utility.uuid()); // 生成IM-TOKEN
|
||||||
|
zimSource.updateColumn(ImUser.class, user.getUserid(), ColumnValue.create("imtoken", user.getImtoken()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//strCache.hset("im:user-token", user.getImtoken(), JsonConvert.root(), user);
|
||||||
|
redisCache.hset("im:user-token", user.getImtoken(), user);
|
||||||
return RetResult.success(Kv.of("token", user.getImtoken()));
|
return RetResult.success(Kv.of("token", user.getImtoken()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +199,7 @@ public class ImAccountService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
@RestMapping(name = "subscribe", auth = false, comment = "给用户订阅频道信息")
|
@RestMapping(name = "subscribe", auth = false, comment = "给用户订阅频道信息")
|
||||||
public RetResult subscribe(SubscribeBean bean) {
|
public RetResult subscribe(SubscribeBean bean) {
|
||||||
ImUser user = accountService.currentImUser(bean.getImtoken());
|
ImUser user = currentImUser(bean.getImtoken());
|
||||||
int userid = user.getUserid();
|
int userid = user.getUserid();
|
||||||
Lock lock = zhub.lock("im:channel-create:" + userid, 500);
|
Lock lock = zhub.lock("im:channel-create:" + userid, 500);
|
||||||
try {
|
try {
|
||||||
@ -220,7 +229,7 @@ public class ImAccountService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
@RestMapping(name = "unsubscribe", auth = false, comment = "取消频道订阅")
|
@RestMapping(name = "unsubscribe", auth = false, comment = "取消频道订阅")
|
||||||
public RetResult unsubscribe(SubscribeBean bean) {
|
public RetResult unsubscribe(SubscribeBean bean) {
|
||||||
ImUser user = accountService.currentImUser(bean.getImtoken());
|
ImUser user = currentImUser(bean.getImtoken());
|
||||||
int userid = user.getUserid();
|
int userid = user.getUserid();
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@ package com.zchd.zim;
|
|||||||
import com.zchd.base.BaseService;
|
import com.zchd.base.BaseService;
|
||||||
import com.zchd.base.util.Kv;
|
import com.zchd.base.util.Kv;
|
||||||
import com.zchd.base.util.QueueTask;
|
import com.zchd.base.util.QueueTask;
|
||||||
|
import com.zchd.base.util.Utils;
|
||||||
|
import com.zchd.zim.bean.ImBean;
|
||||||
|
import com.zchd.zim.bean.MessageBean;
|
||||||
import com.zchd.zim.entity.ChannelMessage;
|
import com.zchd.zim.entity.ChannelMessage;
|
||||||
import com.zchd.zim.entity.ChannelUser;
|
import com.zchd.zim.entity.ChannelUser;
|
||||||
import com.zchd.zim.entity.FriendMessage;
|
import com.zchd.zim.entity.FriendMessage;
|
||||||
@ -11,12 +14,14 @@ import net.tccn.timer.Timers;
|
|||||||
import net.tccn.zhub.ZHubClient;
|
import net.tccn.zhub.ZHubClient;
|
||||||
import org.redkale.net.http.RestService;
|
import org.redkale.net.http.RestService;
|
||||||
import org.redkale.net.http.WebSocketNode;
|
import org.redkale.net.http.WebSocketNode;
|
||||||
|
import org.redkale.service.RetResult;
|
||||||
import org.redkale.source.ColumnValue;
|
import org.redkale.source.ColumnValue;
|
||||||
import org.redkale.source.DataSource;
|
import org.redkale.source.DataSource;
|
||||||
import org.redkale.source.FilterNode;
|
import org.redkale.source.FilterNode;
|
||||||
import org.redkale.source.Flipper;
|
import org.redkale.source.Flipper;
|
||||||
import org.redkale.util.AnyValue;
|
import org.redkale.util.AnyValue;
|
||||||
import org.redkale.util.Comment;
|
import org.redkale.util.Comment;
|
||||||
|
import org.redkale.util.TypeToken;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.persistence.Transient;
|
import javax.persistence.Transient;
|
||||||
@ -39,11 +44,52 @@ public class ImChatService extends BaseService {
|
|||||||
@Transient //消息存储
|
@Transient //消息存储
|
||||||
protected QueueTask<Runnable> dbQueue = new QueueTask<>(1);
|
protected QueueTask<Runnable> dbQueue = new QueueTask<>(1);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ImAccountService accountService;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(AnyValue config) {
|
public void init(AnyValue config) {
|
||||||
msgQueue.init(logger, Runnable::run);
|
msgQueue.init(logger, Runnable::run);
|
||||||
dbQueue.init(logger, Runnable::run);
|
dbQueue.init(logger, Runnable::run);
|
||||||
|
|
||||||
|
zhub.rpcSubscribe("im:send-message", new TypeToken<MessageBean>() {
|
||||||
|
}, r -> {
|
||||||
|
MessageBean bean = r.getValue();
|
||||||
|
|
||||||
|
/*// 当指定点对点消息类型的时候,消息类型必须明确
|
||||||
|
if (!Utils.isEmpty(bean.getGuserid()) && Utils.isEmpty(bean.getMessagetype())) {
|
||||||
|
return r.retError("发送消息类型未明确");
|
||||||
|
}*/
|
||||||
|
if (Utils.isEmpty(bean.getGuserid()) && bean.getReceivechannel() == null) {
|
||||||
|
return r.retError("发送目标未明确");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送点对点消息
|
||||||
|
if (!Utils.isEmpty(bean.getGuserid())) {
|
||||||
|
ImBean imBean = bean.buildImBean();
|
||||||
|
ImUser imUser = accountService.getImUser(imBean);
|
||||||
|
// 接收人未注册 IM 信息,为其注册信息
|
||||||
|
if (imUser == null) {
|
||||||
|
RetResult<Kv> result = accountService.register(imBean);
|
||||||
|
if (!result.isSuccess()) {
|
||||||
|
return r.retError(result.getRetinfo());
|
||||||
|
}
|
||||||
|
imUser = accountService.getImUser(imBean);
|
||||||
|
}
|
||||||
|
|
||||||
|
FriendMessage message = bean.buildFriendMessage(0, imUser.getUserid());
|
||||||
|
sendFriendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送群组消息
|
||||||
|
if (bean.getReceivechannel() != null) {
|
||||||
|
ChannelMessage message = bean.buildChannelMessage(0); // 发送者:0系统发送
|
||||||
|
sendChannelMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.render();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Comment("发送私聊消息")
|
@Comment("发送私聊消息")
|
||||||
@ -56,7 +102,8 @@ public class ImChatService extends BaseService {
|
|||||||
// intCache.incrHm("im:heartbeat:" + uid, "messagecount", -1);
|
// intCache.incrHm("im:heartbeat:" + uid, "messagecount", -1);
|
||||||
// 更新状态失败, 200ms 后重试(当数据未写入的时候,更新失败)
|
// 更新状态失败, 200ms 后重试(当数据未写入的时候,更新失败)
|
||||||
Timers.tryDelay(() -> {
|
Timers.tryDelay(() -> {
|
||||||
FilterNode node = FilterNode.create("senduserid", bean.getSenduserid()).and("receiveuserid", uid);
|
// FilterNode node = FilterNode.create("senduserid", bean.getSenduserid()).and("receiveuserid", uid);
|
||||||
|
FilterNode node = FilterNode.create("messageid", bean.getMessageid());
|
||||||
int updateColumn = zimSource.updateColumn(FriendMessage.class, node, ColumnValue.create("status", 10));
|
int updateColumn = zimSource.updateColumn(FriendMessage.class, node, ColumnValue.create("status", 10));
|
||||||
|
|
||||||
return updateColumn != 0;
|
return updateColumn != 0;
|
||||||
@ -81,7 +128,7 @@ public class ImChatService extends BaseService {
|
|||||||
// 拉取频道离线消息
|
// 拉取频道离线消息
|
||||||
List<ChannelUser> userGroups = userChannels(userid);
|
List<ChannelUser> userGroups = userChannels(userid);
|
||||||
for (ChannelUser userGroup : userGroups) {
|
for (ChannelUser userGroup : userGroups) {
|
||||||
Long lastAcceptTime = longCache.getHm("im:channel:" + userGroup.buildChannelid(), userGroup.getUserid());
|
Long lastAcceptTime = redisCache.hgetLong("im:channel:" + userGroup.buildChannelid(), userGroup.getUserid() + "", 0);
|
||||||
if (lastAcceptTime == null || lastAcceptTime == 0) {
|
if (lastAcceptTime == null || lastAcceptTime == 0) {
|
||||||
lastAcceptTime = userGroup.getCreatetime();
|
lastAcceptTime = userGroup.getCreatetime();
|
||||||
}
|
}
|
||||||
@ -93,7 +140,8 @@ public class ImChatService extends BaseService {
|
|||||||
.and("senduserid", NOTEQUAL, userid)
|
.and("senduserid", NOTEQUAL, userid)
|
||||||
.and("createtime", GREATERTHAN, lastAcceptTime)
|
.and("createtime", GREATERTHAN, lastAcceptTime)
|
||||||
.and("createtime", LESSTHAN, System.currentTimeMillis())
|
.and("createtime", LESSTHAN, System.currentTimeMillis())
|
||||||
.and("status", NOTEQUAL, 80);
|
.and("status", NOTEQUAL, 80)
|
||||||
|
.and("status", NOTEQUAL, 21);
|
||||||
try {
|
try {
|
||||||
List<ChannelMessage> messages = zimSource.queryList(ChannelMessage.class, new Flipper(50, "createtime desc"), node1);
|
List<ChannelMessage> messages = zimSource.queryList(ChannelMessage.class, new Flipper(50, "createtime desc"), node1);
|
||||||
|
|
||||||
@ -110,7 +158,7 @@ public class ImChatService extends BaseService {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
longCache.setHm("im:channel:" + userGroup.buildChannelid(), userGroup.getUserid(), lastAcceptTime);
|
redisCache.hsetLong("im:channel:" + userGroup.buildChannelid(), userGroup.getUserid() + "", lastAcceptTime);
|
||||||
// 变更最后拉取时间
|
// 变更最后拉取时间
|
||||||
/*FilterNode node = FilterNode.create("appid", userGroup.getAppid())
|
/*FilterNode node = FilterNode.create("appid", userGroup.getAppid())
|
||||||
.and("channeltype", userGroup.getChanneltype())
|
.and("channeltype", userGroup.getChanneltype())
|
||||||
@ -129,7 +177,7 @@ public class ImChatService extends BaseService {
|
|||||||
|
|
||||||
@Comment("用户IM是否在线")
|
@Comment("用户IM是否在线")
|
||||||
public boolean userOnline(int userid) {
|
public boolean userOnline(int userid) {
|
||||||
return intCache.getBit("im:user", userid);
|
return redisCache.getBit("im:user", userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Comment("用户在线直接发送, 如果不在线先记录到数据库")
|
@Comment("用户在线直接发送, 如果不在线先记录到数据库")
|
||||||
@ -153,20 +201,26 @@ public class ImChatService extends BaseService {
|
|||||||
zhub.broadcast("im:channel:" + message.buildChannelid(), message);
|
zhub.broadcast("im:channel:" + message.buildChannelid(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getGuserid(int userid) {
|
protected String getGuserid(int userid) {
|
||||||
|
if (userid == 0) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
ImUser user = zimSource.find(ImUser.class, userid);
|
ImUser user = zimSource.find(ImUser.class, userid);
|
||||||
return user.getGuserid();
|
return user.getGuserid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getUserid(String appid, String guserid) {
|
public int getUserid(String appid, String guserid) {
|
||||||
ImUser user = zimSource.find(ImUser.class, FilterNode.create("appid", appid).and("guserid", guserid));
|
ImUser user = zimSource.find(ImUser.class, FilterNode.create("appid", appid).and("guserid", guserid));
|
||||||
|
if (user == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return user.getUserid();
|
return user.getUserid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Kv buildFriendMessageDeail(FriendMessage message) {
|
public Kv buildFriendMessageDeail(FriendMessage message) {
|
||||||
Kv detail = Kv.toKv(message, "content", "messageid", "sendtime");
|
Kv detail = Kv.toKv(message, "content", "messageid", "sendtime");
|
||||||
detail.set("sendguserid", getGuserid(message.getSenduserid()));
|
detail.set("sendguserid", getGuserid(message.getSenduserid()));
|
||||||
Kv data = Kv.of("detail", detail).set("type", "friend-text");
|
Kv data = Kv.of("detail", detail).set("type", message.getMessagetype());
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package com.zchd.zim;
|
package com.zchd.zim;
|
||||||
|
|
||||||
|
import com.zchd.base.RedissionCacheSourcex;
|
||||||
import com.zchd.base.info.SwearWordService;
|
import com.zchd.base.info.SwearWordService;
|
||||||
import com.zchd.base.util.Kv;
|
import com.zchd.base.util.Kv;
|
||||||
import com.zchd.base.util.Utils;
|
import com.zchd.base.util.Utils;
|
||||||
import com.zchd.zim.entity.ChannelMessage;
|
import com.zchd.zim.entity.ChannelMessage;
|
||||||
import com.zchd.zim.entity.FriendMessage;
|
import com.zchd.zim.entity.FriendMessage;
|
||||||
import com.zchd.zim.entity.ImUser;
|
import com.zchd.zim.entity.ImUser;
|
||||||
|
import net.tccn.zhub.ZHubClient;
|
||||||
import org.redkale.net.http.HttpRequest;
|
import org.redkale.net.http.HttpRequest;
|
||||||
import org.redkale.net.http.RestOnMessage;
|
import org.redkale.net.http.RestOnMessage;
|
||||||
import org.redkale.net.http.RestWebSocket;
|
import org.redkale.net.http.RestWebSocket;
|
||||||
@ -13,7 +15,6 @@ import org.redkale.net.http.WebSocket;
|
|||||||
import org.redkale.service.RetResult;
|
import org.redkale.service.RetResult;
|
||||||
import org.redkale.source.DataSource;
|
import org.redkale.source.DataSource;
|
||||||
import org.redkale.util.Comment;
|
import org.redkale.util.Comment;
|
||||||
import org.redkalex.cache.redis.MyRedisCacheSource;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -27,9 +28,11 @@ public class ImChatWebSocket extends WebSocket {
|
|||||||
|
|
||||||
@Resource(name = "z_im")
|
@Resource(name = "z_im")
|
||||||
protected DataSource zimSource;
|
protected DataSource zimSource;
|
||||||
|
@Resource(name = "redis")
|
||||||
|
protected RedissionCacheSourcex redisCache;
|
||||||
|
|
||||||
@Resource(name = "int_cache")
|
@Resource(name = "zhub")
|
||||||
protected MyRedisCacheSource<Integer> intCache;
|
protected ZHubClient zhub;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
protected ImAccountService accountService;
|
protected ImAccountService accountService;
|
||||||
@ -74,7 +77,9 @@ public class ImChatWebSocket extends WebSocket {
|
|||||||
return CompletableFuture.runAsync(() -> {
|
return CompletableFuture.runAsync(() -> {
|
||||||
final int userid = (int) getUserid();
|
final int userid = (int) getUserid();
|
||||||
getLogger().info("im:state-change:" + userid + "---ws connected---");
|
getLogger().info("im:state-change:" + userid + "---ws connected---");
|
||||||
intCache.setBit("im:user", userid, true);
|
redisCache.setBit("im:user", userid, true);
|
||||||
|
// 推送上线状态
|
||||||
|
zhub.publish("im:online:" + getAttribute("appid"), getAttribute("guserid"));
|
||||||
// 上线开启订阅
|
// 上线开启订阅
|
||||||
messageMonitor.online(userid);
|
messageMonitor.online(userid);
|
||||||
// 拉取离线消息
|
// 拉取离线消息
|
||||||
@ -95,10 +100,14 @@ public class ImChatWebSocket extends WebSocket {
|
|||||||
String mck = extmap.get("mck");
|
String mck = extmap.get("mck");
|
||||||
|
|
||||||
int targetguserid = chatService.getUserid(appid, guserid);
|
int targetguserid = chatService.getUserid(appid, guserid);
|
||||||
|
if (targetguserid == 0) {
|
||||||
|
sendTip("用户不存在", mck, 4001);
|
||||||
|
return;
|
||||||
|
}
|
||||||
FriendMessage message = FriendMessage.buildFriendMessage(bean.get("content"), userid, targetguserid);
|
FriendMessage message = FriendMessage.buildFriendMessage(bean.get("content"), userid, targetguserid);
|
||||||
|
|
||||||
// 禁言检查
|
// 禁言检查
|
||||||
if (intCache.getBit("im:banned-talk", userid)) {
|
if (redisCache.getBit("im:banned-talk", userid)) {
|
||||||
sendTip("发送失败,你已被禁言", mck, 3002);
|
sendTip("发送失败,你已被禁言", mck, 3002);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -133,7 +142,7 @@ public class ImChatWebSocket extends WebSocket {
|
|||||||
String mck = extmap.get("mck");
|
String mck = extmap.get("mck");
|
||||||
|
|
||||||
// 禁言检查
|
// 禁言检查
|
||||||
if (intCache.getBit("im:banned-talk", userid)) {
|
if (redisCache.getBit("im:banned-talk", userid)) {
|
||||||
sendTip("发送失败,你已被禁言", mck, 3002);
|
sendTip("发送失败,你已被禁言", mck, 3002);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -166,7 +175,9 @@ public class ImChatWebSocket extends WebSocket {
|
|||||||
public CompletableFuture onClose(int code, String reason) {
|
public CompletableFuture onClose(int code, String reason) {
|
||||||
final int userid = (int) getUserid();
|
final int userid = (int) getUserid();
|
||||||
getLogger().info("im:state-change:" + userid + "---close---" + code + "---" + reason);
|
getLogger().info("im:state-change:" + userid + "---close---" + code + "---" + reason);
|
||||||
intCache.setBit("im:user:", userid, false);
|
redisCache.setBit("im:user", userid, false);
|
||||||
|
// 推送离线状态
|
||||||
|
zhub.publish("im:offline:" + getAttribute("appid"), getAttribute("guserid"));
|
||||||
// 取消用户订阅
|
// 取消用户订阅
|
||||||
messageMonitor.offline(userid);
|
messageMonitor.offline(userid);
|
||||||
return null;
|
return null;
|
||||||
|
@ -13,7 +13,6 @@ import org.redkale.util.AnyValue;
|
|||||||
import org.redkale.util.Comment;
|
import org.redkale.util.Comment;
|
||||||
import org.redkale.util.TypeToken;
|
import org.redkale.util.TypeToken;
|
||||||
import org.redkale.util.Utility;
|
import org.redkale.util.Utility;
|
||||||
import org.redkalex.cache.redis.MyRedisCacheSource;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
@ -32,11 +31,6 @@ public class ImMessageMonitor extends BaseService {
|
|||||||
@Resource(name = "im_chat")
|
@Resource(name = "im_chat")
|
||||||
protected WebSocketNode wsnode;
|
protected WebSocketNode wsnode;
|
||||||
|
|
||||||
@Resource(name = "int_cache")
|
|
||||||
protected MyRedisCacheSource<Integer> intCache;
|
|
||||||
@Resource(name = "long_cache")
|
|
||||||
protected MyRedisCacheSource<Long> longCache;
|
|
||||||
|
|
||||||
protected BitSet bitSet = new BitSet(); // IM用户连接当前实例记录
|
protected BitSet bitSet = new BitSet(); // IM用户连接当前实例记录
|
||||||
|
|
||||||
protected ConcurrentHashMap<String, Set<Integer>> channelSubscribe = new ConcurrentHashMap<>();
|
protected ConcurrentHashMap<String, Set<Integer>> channelSubscribe = new ConcurrentHashMap<>();
|
||||||
@ -122,7 +116,7 @@ public class ImMessageMonitor extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo:并发场景下,会影响拉取离线消息
|
// todo:并发场景下,会影响拉取离线消息
|
||||||
longCache.setHm("im:channel:" + x.buildChannelid(), uid, System.currentTimeMillis());
|
redisCache.hset("im:channel:" + x.buildChannelid(), uid + "", System.currentTimeMillis());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
68
src/com/zchd/zim/bean/MessageBean.java
Normal file
68
src/com/zchd/zim/bean/MessageBean.java
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package com.zchd.zim.bean;
|
||||||
|
|
||||||
|
import com.zchd.base.util.Utils;
|
||||||
|
import com.zchd.zim.entity.AppInfo;
|
||||||
|
import com.zchd.zim.entity.ChannelMessage;
|
||||||
|
import com.zchd.zim.entity.FriendMessage;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.redkale.util.Comment;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class MessageBean {
|
||||||
|
|
||||||
|
@Column(comment = "[消息内容]")
|
||||||
|
private String content = "";
|
||||||
|
|
||||||
|
@Column(comment = "[平台信息]{appid, appsecret}")
|
||||||
|
private AppInfo appinfo;
|
||||||
|
|
||||||
|
@Column(comment = "[消息类型]用于点对点模式下的消息类别标注")
|
||||||
|
private String messagetype = "";
|
||||||
|
|
||||||
|
@Column(comment = "[接收人]")
|
||||||
|
private String guserid;
|
||||||
|
|
||||||
|
@Comment("[接收群组]{channeltype, channelvalue}")
|
||||||
|
private SubscribeBean receivechannel;
|
||||||
|
|
||||||
|
@Column(comment = "[仅在线接收]0否、1是")
|
||||||
|
private short onlinereceive = 0;
|
||||||
|
|
||||||
|
public FriendMessage buildFriendMessage(int senduserid, int userid) {
|
||||||
|
FriendMessage message = new FriendMessage();
|
||||||
|
message.setContent(content);
|
||||||
|
message.setMessagetype(messagetype);
|
||||||
|
message.setSenduserid(senduserid);
|
||||||
|
message.setReceiveuserid(userid);
|
||||||
|
message.setCreatetime(System.currentTimeMillis());
|
||||||
|
message.setStatus(onlinereceive == 1 ? (short) 21 : 20);
|
||||||
|
message.setMessageid(Utils.fmt36(senduserid) + "-" + Utils.fmt36(message.getCreatetime()));
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelMessage buildChannelMessage(int senduserid) {
|
||||||
|
ChannelMessage message = new ChannelMessage();
|
||||||
|
message.setContent(content);
|
||||||
|
message.setAppid(appinfo.getAppid());
|
||||||
|
message.setSenduserid(senduserid);
|
||||||
|
message.setChanneltype(receivechannel.getChanneltype());
|
||||||
|
message.setChannelvalue(receivechannel.getChannelvalue());
|
||||||
|
message.setCreatetime(System.currentTimeMillis());
|
||||||
|
message.setStatus(onlinereceive == 1 ? (short) 21 : 20);
|
||||||
|
message.setMessageid(Utils.fmt36(message.getSenduserid()) + "-" + Utils.fmt36(message.getCreatetime()));
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImBean buildImBean() {
|
||||||
|
ImBean bean = new ImBean();
|
||||||
|
bean.setAppid(appinfo.getAppid());
|
||||||
|
bean.setAppsecret(appinfo.getAppsecret());
|
||||||
|
bean.setGuserid(guserid);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,9 @@ public class FriendMessage {
|
|||||||
@Column(comment = "[私聊ID]发送人-时间戳")
|
@Column(comment = "[私聊ID]发送人-时间戳")
|
||||||
private String messageid = "";
|
private String messageid = "";
|
||||||
|
|
||||||
|
@Column(comment = "[消息类型]")
|
||||||
|
private String messagetype = "friend-text";
|
||||||
|
|
||||||
@Column(comment = "[私聊内容]")
|
@Column(comment = "[私聊内容]")
|
||||||
private String content = "";
|
private String content = "";
|
||||||
|
|
||||||
@ -29,7 +32,7 @@ public class FriendMessage {
|
|||||||
@Column(comment = "[创建时间]")
|
@Column(comment = "[创建时间]")
|
||||||
private long createtime;
|
private long createtime;
|
||||||
|
|
||||||
@Column(comment = "[状态]10已发送,20未发送")
|
@Column(comment = "[状态]10已发送,20未发送,21仅在线发送")
|
||||||
private short status;
|
private short status;
|
||||||
|
|
||||||
public static FriendMessage buildFriendMessage(String content, int senduserid, int receiveuserid) {
|
public static FriendMessage buildFriendMessage(String content, int senduserid, int receiveuserid) {
|
||||||
|
Loading…
Reference in New Issue
Block a user