Browse Source

直播模块

tags/正式3.2.0
雍文秀 2 years ago
parent
commit
187a4060e0

+ 5
- 0
slive/pom.xml View File

76
             <artifactId>httpclient</artifactId>
76
             <artifactId>httpclient</artifactId>
77
             <version>4.5.9</version>
77
             <version>4.5.9</version>
78
         </dependency>
78
         </dependency>
79
+        <!--amqp的起步依赖-->
80
+        <dependency>
81
+            <groupId>org.springframework.boot</groupId>
82
+            <artifactId>spring-boot-starter-amqp</artifactId>
83
+        </dependency>
79
     </dependencies>
84
     </dependencies>
80
     <dependencyManagement>
85
     <dependencyManagement>
81
         <dependencies>
86
         <dependencies>

+ 23
- 0
slive/src/main/java/com/xhkjedu/slive/config/RabbitConfig.java View File

1
+package com.xhkjedu.slive.config;
2
+
3
+import org.springframework.amqp.core.Queue;
4
+import org.springframework.beans.factory.annotation.Value;
5
+import org.springframework.context.annotation.Bean;
6
+import org.springframework.context.annotation.Configuration;
7
+
8
+/**
9
+ * @author ywx
10
+ * @classname RabbitConfig
11
+ * @description
12
+ * @date 2021/6/18 12:51
13
+ **/
14
+@Configuration
15
+public class RabbitConfig {
16
+    @Value("${rabbitmq.queue}")
17
+    private String rabbitmqQueue;
18
+
19
+    @Bean
20
+    public Queue queueA() {
21
+        return new Queue(rabbitmqQueue); //队列持久
22
+    }
23
+}

+ 34
- 0
slive/src/main/java/com/xhkjedu/slive/config/ScheduledConfig.java View File

1
+package com.xhkjedu.slive.config;
2
+
3
+import org.springframework.context.annotation.Bean;
4
+import org.springframework.context.annotation.Condition;
5
+import org.springframework.context.annotation.ConditionContext;
6
+import org.springframework.context.annotation.Conditional;
7
+import org.springframework.context.annotation.Configuration;
8
+import org.springframework.core.type.AnnotatedTypeMetadata;
9
+import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
10
+
11
+/**
12
+ * @author ywx
13
+ * @className ScheduledConfig
14
+ * @description @Scheduled 注解,是被一个叫做 ScheduledAnnotationBeanPostProcessor 的类所拦截的,
15
+ * 所以我们可以根据配置,决定是否创建这个 bean,如果没有这个 bean,@Scheduled 就不会被拦截,那么定时任务肯定不会执行了,
16
+ * 需要注意的是:这种方式,启动类上面的 @EnableScheduling 需要去掉。
17
+ * @date 2021/5/18 9:15
18
+ **/
19
+@Configuration
20
+public class ScheduledConfig {
21
+    @Conditional(ScheduledCondition.class)
22
+    @Bean
23
+    public ScheduledAnnotationBeanPostProcessor processor(){
24
+        return new ScheduledAnnotationBeanPostProcessor();
25
+    }
26
+}
27
+
28
+class ScheduledCondition implements Condition{
29
+
30
+    @Override
31
+    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
32
+        return Boolean.valueOf(context.getEnvironment().getProperty("enable.scheduled"));
33
+    }
34
+}

+ 34
- 0
slive/src/main/java/com/xhkjedu/slive/listener/MessageConsumer.java View File

1
+package com.xhkjedu.slive.listener;
2
+
3
+import com.alibaba.fastjson.JSON;
4
+import com.rabbitmq.client.Channel;
5
+import com.xhkjedu.slive.model.liveplay.LCourseSectionPlayback;
6
+import com.xhkjedu.slive.service.liveplay.CourseSectionPlaybackService;
7
+import lombok.extern.slf4j.Slf4j;
8
+import org.springframework.amqp.core.Message;
9
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
10
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
11
+import org.springframework.stereotype.Component;
12
+
13
+import javax.annotation.Resource;
14
+import java.time.LocalDateTime;
15
+
16
+/**
17
+ * 消息到达消费者监听类
18
+ */
19
+@Component
20
+@Slf4j
21
+public class MessageConsumer {
22
+    @Resource
23
+    private CourseSectionPlaybackService courseSectionPlaybackService;
24
+
25
+    //处理收到的rabbit消息的回调方法
26
+    @RabbitHandler
27
+    @RabbitListener(queues = "${rabbitmq.queue}")
28
+    public void onMessage(Message message, Channel channel) throws Exception {
29
+        String msg = new String(message.getBody(), "UTF-8");
30
+        System.out.println(LocalDateTime.now()+" 接收消息内容:"+msg);
31
+        LCourseSectionPlayback playback = JSON.parseObject(msg,LCourseSectionPlayback.class);
32
+        courseSectionPlaybackService.updatePlayback(playback);
33
+    }
34
+}

+ 59
- 0
slive/src/main/java/com/xhkjedu/slive/task/LivePlayTask.java View File

1
+package com.xhkjedu.slive.task;
2
+
3
+import com.xhkjedu.slive.service.agora.AgoralicenseService;
4
+import com.xhkjedu.slive.service.liveplay.CourseSectionService;
5
+import org.springframework.scheduling.annotation.Scheduled;
6
+import org.springframework.stereotype.Component;
7
+
8
+import javax.annotation.Resource;
9
+import java.util.Date;
10
+
11
+/**
12
+ * @author ywx
13
+ * @classname LivePlayTask
14
+ * @description
15
+ * @date 2021/1/16 13:30
16
+ **/
17
+@Component
18
+public class LivePlayTask {
19
+
20
+    @Resource
21
+    private CourseSectionService courseSectionService;
22
+    @Resource
23
+    private AgoralicenseService agoralicenseService;
24
+
25
+    /**
26
+     * 定时任务修改课节状态
27
+     * @Param []
28
+     * @Author ywx
29
+     * @Date 2021/1/16 13:34
30
+     * @return void
31
+     **/
32
+    @Scheduled(cron = "${cron.updateSectionState}")
33
+    public void updateSectionState(){
34
+        try {
35
+            System.out.println(new Date());
36
+            courseSectionService.updateSectionState2();
37
+        } catch (Exception e) {
38
+            System.out.println("定时任务修改课节状态异常:"+e.getCause().getMessage());
39
+        }
40
+    }
41
+
42
+    /**
43
+     * 定时任务修改license状态
44
+     * @Param []
45
+     * @Author ywx
46
+     * @Date 2021/4/7 10:10
47
+     * @return void
48
+     **/
49
+    @Scheduled(cron = "${cron.updateLicenseState}")
50
+    public void updateLicenseState() {
51
+        agoralicenseService.updateLicenseState();
52
+    }
53
+
54
+    //处理未释放的授权
55
+    @Scheduled(cron = "${cron.updateLicense}")
56
+    public void updateLicense() {
57
+        agoralicenseService.updateLicense();
58
+    }
59
+}

+ 29
- 0
slive/src/main/resources/application.properties View File

52
 redisdatatime=604800
52
 redisdatatime=604800
53
 #secretKey必须为24位
53
 #secretKey必须为24位
54
 secretKey=nanhuakaizhangjianwangni
54
 secretKey=nanhuakaizhangjianwangni
55
+
55
 #ws地址
56
 #ws地址
56
 ws.address=ws://39.104.164.162:8917/ws,ws://39.104.164.162:8918/ws
57
 ws.address=ws://39.104.164.162:8917/ws,ws://39.104.164.162:8918/ws
57
 #云平台接口地址
58
 #云平台接口地址
58
 cloudapi=http://scapitest.xhkjedu.com/
59
 cloudapi=http://scapitest.xhkjedu.com/
60
+
59
 #声网
61
 #声网
60
 #APP ID
62
 #APP ID
61
 agora.appId=b1b07f9eeb2444d0b7ff2205e072b973
63
 agora.appId=b1b07f9eeb2444d0b7ff2205e072b973
67
 agora.license.key=2cb21d4aadb44dbca60263df0ab9213d
69
 agora.license.key=2cb21d4aadb44dbca60263df0ab9213d
68
 #license 密钥
70
 #license 密钥
69
 agora.license.secret=e2439c74719940649aa754ef8c79369d
71
 agora.license.secret=e2439c74719940649aa754ef8c79369d
72
+
73
+rabbitmq.queue=xhkjedu.xhschool.livequeue_dev_bd
74
+spring.rabbitmq.host=116.63.199.166
75
+spring.rabbitmq.port=5672
76
+spring.rabbitmq.username=xhkjedu
77
+spring.rabbitmq.password=xhkjedud07
78
+spring.rabbitmq.connection-timeout=15000
79
+#rabbitmq自动签收
80
+spring.rabbitmq.listener.simple.acknowledge-mode=auto
81
+# 是否开启消费者重试(为false时关闭消费者重试)
82
+spring.rabbitmq.listener.simple.retry.enabled=true
83
+# 最大重试重新投递消息次数
84
+spring.rabbitmq.listener.simple.retry.max-attempts=3
85
+# 重试重新投递消息的间隔时间(单位毫秒)
86
+spring.rabbitmq.listener.simple.retry.initial-interval=30000ms
87
+#重试次数超过上面的设置之后,是否丢弃(消费者listener抛出异常,是否重回队列(默认true:重回队列,false:不重回队列(可结合死信交换机))
88
+spring.rabbitmq.listener.simple.default-requeue-rejected=false
89
+
90
+#定时任务
91
+#每隔1分钟修改课节状态
92
+cron.updateSectionState=0 0/1 * * * ?
93
+#每天凌晨处理未释放的授权
94
+cron.updateLicense=0 0 0 * * ?
95
+#每隔1小时修改license状态
96
+cron.updateLicenseState=0 0 0/1 * * ?
97
+#默认为false,不开启定时任务
98
+enable.scheduled=true

+ 61
- 0
slive/src/main/resources/mapper/agora/AgoralicenseMapper.xml View File

1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3
+<mapper namespace="com.xhkjedu.slive.mapper.agora.AgoralicenseMapper">
4
+    <!--列表-->
5
+    <select id="listAll" resultType="com.xhkjedu.slive.vo.agora.AgoralicenseVo">
6
+        select l.agid, l.custom, l.cert, l.credential, l.activated, l.used, l.userid, l.createid, l.createtime
7
+        ,min(lr.activatedtime)starttime,(max(lr.activatedtime)+lr.validityperiod*24*60*60)endtime
8
+        ,l.username,l.loginname,l.cloudcode,c.cloudname
9
+        from t_agoralicense l left join t_agoralicense_record lr on l.agid = lr.agid
10
+        left join t_cloud c on l.cloudcode=c.cloudcode
11
+        <where>
12
+            <if test="license.activated!=null">and l.activated=#{license.activated}</if>
13
+            <if test="license.used!=null">and l.used=#{license.used}</if>
14
+            <if test="license.cloudcode!=null">and l.cloudcode=#{license.cloudcode}</if>
15
+        </where>
16
+        group by l.agid
17
+    </select>
18
+    <!--进入直播绑定license-->
19
+    <select id="inLive" resultType="com.xhkjedu.slive.vo.agora.AgoralicenseVo">
20
+        select agid, custom, cert, credential, activated, used, cloudcode, userid, createid, createtime
21
+        from t_agoralicense where userid=#{userid} and activated=1 limit 1
22
+    </select>
23
+    <!--获取已激活license-->
24
+    <select id="getActivatedLicense" resultType="com.xhkjedu.slive.vo.agora.AgoralicenseVo">
25
+        select agid, custom, cert, credential, activated, used, cloudcode, userid, createid, createtime
26
+        from t_agoralicense where activated=1 and used=0 order by rand() limit 1
27
+    </select>
28
+    <!--获取未激活license-->
29
+    <select id="getLicense" resultType="com.xhkjedu.slive.vo.agora.AgoralicenseVo">
30
+        select agid, custom, cert, credential, activated, used, cloudcode, userid, createid, createtime
31
+        from t_agoralicense where activated=0 order by rand() limit 1
32
+    </select>
33
+    <!--退出直播解绑license-->
34
+    <update id="outLive">
35
+        update t_agoralicense set used=0,cloudcode=null,schoolid=null,userid=0,username=null,loginname=null
36
+        where userid=#{userid};
37
+    </update>
38
+    <!--处理未释放的授权-->
39
+    <update id="updateLicense">
40
+        update t_agoralicense set used=0,cloudcode=null,schoolid=null,userid=0,username=null,loginname=null where used=1
41
+    </update>
42
+    <!--更新失效的license的激活状态-->
43
+    <update id="updateActivate">
44
+        update (SELECT agid,(max(activatedtime)+validityperiod*24*60*60)activatedtime
45
+        FROM t_agoralicense_record GROUP BY agid)r LEFT JOIN t_agoralicense l ON r.agid=l.agid
46
+        set l.activated=2
47
+        WHERE r.activatedtime<![CDATA[ < ]]>UNIX_TIMESTAMP(NOW());
48
+    </update>
49
+    <update id="endLive2">
50
+        update t_agoralicense l set
51
+        l.used=0,l.cloudcode=null,l.schoolid=null,l.userid=0,l.username=null,l.loginname=null
52
+        where (
53
+        <foreach collection="license.userids" item="userid" index="index" separator="or">
54
+            l.userid=#{userid}
55
+        </foreach>)
56
+    </update>
57
+    <!--获取学校正在使用直播人数-->
58
+    <select id="getUseNum" resultType="java.lang.Integer">
59
+        select count(*) from t_agoralicense where schoolid=#{schoolid} and used=1 and userid!=#{userid}
60
+    </select>
61
+</mapper>

Loading…
Cancel
Save