[+] 重写媒体事件模型

This commit is contained in:
acgist
2023-03-10 08:14:19 +08:00
parent fe7bc4baf9
commit 63a37be492
32 changed files with 558 additions and 162 deletions

View File

@@ -19,10 +19,6 @@ public interface Constant {
* IP
*/
String IP = "ip";
/**
* 动作
*/
String ACTIVE = "active";
/**
* 状态对象
*/
@@ -219,6 +215,10 @@ public interface Constant {
* SCTP协商
*/
String SCTP_CAPABILITIES = "sctpCapabilities";
/**
* 状态
*/
String ENABLED = "enabled";
/**
* 是否是消费者
*/

View File

@@ -6,14 +6,22 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.acgist.taoyao.boot.config.MediaAudioProperties;
import com.acgist.taoyao.boot.config.MediaVideoProperties;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.config.camera.AiProperties;
import com.acgist.taoyao.signal.config.camera.BeautyProperties;
import com.acgist.taoyao.signal.config.camera.WatermarkProperties;
import com.acgist.taoyao.signal.model.control.PtzControl;
import com.acgist.taoyao.signal.protocol.control.ControlAiProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlBeautyProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlBellProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlConfigAudioProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlConfigVideoProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlPhotographProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlPtzProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlRecordProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlWatermarkProtocol;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -34,51 +42,87 @@ public class ControlController {
private final ControlAiProtocol controlAiProtocol;
private final ControlPtzProtocol controlPtzProtocol;
private final ControlBellProtocol controlBellProtocol;
private final ControlBeautyProtocol controlBeautyProtocol;
private final ControlRecordProtocol controlRecordProtocol;
private final ControlWatermarkProtocol controlWatermarkProtocol;
private final ControlPhotographProtocol controlPhotographProtocol;
private final ControlConfigAudioProtocol controlConfigAudioProtocol;
private final ControlConfigVideoProtocol controlConfigVideoProtocol;
public ControlController(
ControlAiProtocol controlAiProtocol,
ControlPtzProtocol controlPtzProtocol,
ControlBellProtocol controlBellProtocol,
ControlBeautyProtocol controlBeautyProtocol,
ControlRecordProtocol controlRecordProtocol,
ControlPhotographProtocol controlPhotographProtocol
ControlWatermarkProtocol controlWatermarkProtocol,
ControlPhotographProtocol controlPhotographProtocol,
ControlConfigAudioProtocol controlConfigAudioProtocol,
ControlConfigVideoProtocol controlConfigVideoProtocol
) {
this.controlAiProtocol = controlAiProtocol;
this.controlPtzProtocol = controlPtzProtocol;
this.controlBellProtocol = controlBellProtocol;
this.controlBeautyProtocol = controlBeautyProtocol;
this.controlRecordProtocol = controlRecordProtocol;
this.controlWatermarkProtocol = controlWatermarkProtocol;
this.controlPhotographProtocol = controlPhotographProtocol;
this.controlConfigAudioProtocol = controlConfigAudioProtocol;
this.controlConfigVideoProtocol = controlConfigVideoProtocol;
}
@Operation(summary = "AI识别", description = "AI识别")
@Operation(summary = "AI识别", description = "AI识别控制")
@GetMapping("/ai/{clientId}")
public Message ai(@PathVariable String clientId, @Valid AiProperties aiProperties) {
return Message.success(this.controlAiProtocol.execute(clientId, aiProperties));
}
@Operation(summary = "PTZ", description = "PTZ")
@Operation(summary = "PTZ", description = "PTZ控制")
@GetMapping("/ptz/{clientId}")
public Message ptz(@PathVariable String clientId, @Valid PtzControl ptzControl) {
return Message.success(this.controlPtzProtocol.execute(clientId, ptzControl));
}
@Operation(summary = "响铃", description = "响铃")
@Operation(summary = "响铃", description = "响铃控制")
@GetMapping("/bell/{clientId}")
public Message bell(@PathVariable String clientId, @NotNull(message = "没有指定操作") Boolean active) {
return Message.success(this.controlBellProtocol.execute(clientId, active));
public Message bell(@PathVariable String clientId, @NotNull(message = "没有指定操作状态") Boolean enabled) {
return Message.success(this.controlBellProtocol.execute(clientId, enabled));
}
@Operation(summary = "录像", description = "录像")
@Operation(summary = "美颜", description = "美颜控制")
@GetMapping("/beauty/{clientId}")
public Message beauty(@PathVariable String clientId, @Valid BeautyProperties beautyProperties) {
return Message.success(this.controlBeautyProtocol.execute(clientId, beautyProperties));
}
@Operation(summary = "录像", description = "录像控制")
@GetMapping("/record/{clientId}")
public Message record(@PathVariable String clientId, @NotNull(message = "没有指定操作") Boolean active) {
return Message.success(this.controlRecordProtocol.execute(clientId, active));
public Message record(@PathVariable String clientId, @NotNull(message = "没有指定操作状态") Boolean enabled) {
return Message.success(this.controlRecordProtocol.execute(clientId, enabled));
}
@Operation(summary = "拍照", description = "拍照")
@Operation(summary = "水印", description = "水印控制")
@GetMapping("/watermark/{clientId}")
public Message watermark(@PathVariable String clientId, @Valid WatermarkProperties watermarkProperties) {
return Message.success(this.controlWatermarkProtocol.execute(clientId, watermarkProperties));
}
@Operation(summary = "拍照", description = "拍照控制")
@GetMapping("/photograph/{clientId}")
public Message photograph(@PathVariable String clientId) {
return Message.success(this.controlPhotographProtocol.execute(clientId));
}
@Operation(summary = "配置音频", description = "配置音频")
@GetMapping("/config/audio/{clientId}")
public Message configAudio(@PathVariable String clientId, @Valid MediaAudioProperties mediaAudioProperties) {
return Message.success(this.controlConfigAudioProtocol.execute(clientId, mediaAudioProperties));
}
@Operation(summary = "配置视频", description = "配置视频")
@GetMapping("/config/video/{clientId}")
public Message configVideo(@PathVariable String clientId, @Valid MediaVideoProperties mediaVideoProperties) {
return Message.success(this.controlConfigVideoProtocol.execute(clientId, mediaVideoProperties));
}
}

View File

@@ -22,6 +22,8 @@ import lombok.extern.slf4j.Slf4j;
/**
* Socket信令
*
* TODO加密
*
* @author acgist
*/
@Slf4j

View File

@@ -28,10 +28,9 @@ public class AiProperties {
}
@Schema(title = "是否开启", description = "是否开启")
@NotNull(message = "没有指定操作")
@NotNull(message = "没有指定操作状态")
private Boolean enabled;
@Schema(title = "识别类型", description = "识别类型")
@NotNull(message = "无效识别类型")
private Type type;
}

View File

@@ -1,6 +1,7 @@
package com.acgist.taoyao.signal.config.camera;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
@@ -15,6 +16,7 @@ import lombok.Setter;
public class BeautyProperties {
@Schema(title = "是否开启", description = "是否开启")
@NotNull(message = "没有指定操作状态")
private Boolean enabled;
@Schema(title = "美颜级别", description = "美颜级别")
private Integer level;

View File

@@ -1,6 +1,7 @@
package com.acgist.taoyao.signal.config.camera;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
@@ -15,6 +16,7 @@ import lombok.Setter;
public class WatermarkProperties {
@Schema(title = "是否开启", description = "是否开启")
@NotNull(message = "没有指定操作状态")
private Boolean enabled;
@Schema(title = "水印内容", description = "水印内容")
private String text;

View File

@@ -3,6 +3,7 @@ package com.acgist.taoyao.signal.event;
import java.util.Map;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.party.media.Room;
import lombok.Getter;
@@ -34,5 +35,12 @@ public class RoomEventAdapter extends ApplicationEventAdapter {
super(room, message, body);
this.room = room;
}
/**
* @return 房间媒体服务终端
*/
public Client getMediaClient() {
return this.room.getMediaClient();
}
}

View File

@@ -0,0 +1,19 @@
package com.acgist.taoyao.signal.event.room;
import com.acgist.taoyao.signal.event.RoomEventAdapter;
import com.acgist.taoyao.signal.party.media.Room;
/**
* 关闭房间事件
*
* @author acgist
*/
public class RoomCloseEvent extends RoomEventAdapter {
private static final long serialVersionUID = 1L;
public RoomCloseEvent(Room room) {
super(room);
}
}

View File

@@ -152,7 +152,7 @@ public class ClientWrapper implements AutoCloseable {
}
@Override
public void close() throws Exception {
public void close() {
// TODO释放资源通道、消费者、生产者
this.consumers.forEach((k, v) -> v.close());
this.producers.forEach((k, v) -> v.close());

View File

@@ -1,7 +1,5 @@
package com.acgist.taoyao.signal.party.media;
import java.io.Closeable;
import com.acgist.taoyao.signal.event.EventPublisher;
import com.acgist.taoyao.signal.event.media.MediaConsumerCloseEvent;
@@ -17,12 +15,8 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Getter
@Setter
public class Consumer implements Closeable {
public class Consumer extends OperatorAdapter {
/**
* 是否关闭
*/
private volatile boolean close = false;
/**
* 媒体类型
*/
@@ -59,14 +53,18 @@ public class Consumer implements Closeable {
@Override
public void close() {
if(this.close) {
if(this.markClose()) {
return;
}
this.close = true;
log.info("关闭消费者:{} - {}", this.streamId, this.consumerId);
EventPublisher.publishEvent(new MediaConsumerCloseEvent(this.consumerId, this.room));
}
@Override
public void remove() {
this.getProducer().remove(this.consumerId);
this.consumerClient.getConsumers().remove(this.consumerId);
EventPublisher.publishEvent(new MediaConsumerCloseEvent(this.consumerId, this.room));
log.info("移除消费者:{} - {}", this.streamId, this.consumerId);
}
/**

View File

@@ -0,0 +1,34 @@
package com.acgist.taoyao.signal.party.media;
import java.io.Closeable;
/**
* 操作接口
* 所有操作直接发出事件
*
* @author acgist
*/
public interface Operator extends Closeable {
/**
* 关闭资源
*/
@Override
void close();
/**
* 移除资源
*/
void remove();
/**
* 暂停资源
*/
void pause();
/**
* 恢复资源
*/
void resume();
}

View File

@@ -0,0 +1,34 @@
package com.acgist.taoyao.signal.party.media;
/**
* 关闭移除接口适配器
*
* @author acgist
*/
public abstract class OperatorAdapter implements Operator {
/**
* 是否关闭
*/
protected volatile boolean close = false;
@Override
public void pause() {
}
@Override
public void resume() {
}
/**
* 标记关闭
*
* @return 是否已经关闭
*/
protected boolean markClose() {
final boolean old = this.close;
this.close = true;
return old;
}
}

View File

@@ -1,6 +1,5 @@
package com.acgist.taoyao.signal.party.media;
import java.io.Closeable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -10,6 +9,7 @@ import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientStatus;
import com.acgist.taoyao.signal.event.EventPublisher;
import com.acgist.taoyao.signal.event.room.RoomCloseEvent;
import com.acgist.taoyao.signal.event.room.RoomLeaveEvent;
import lombok.Getter;
@@ -25,12 +25,8 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Getter
@Setter
public class Room implements Closeable {
public class Room extends OperatorAdapter {
/**
* 是否关闭
*/
private volatile boolean close = false;
/**
* 房间标识
*/
@@ -230,14 +226,18 @@ public class Room implements Closeable {
@Override
public void close() {
if(this.close) {
if(this.markClose()) {
return;
}
this.close = true;
log.info("关闭房间:{}", this.roomId);
// TODO关闭房间
// TODO媒体服务直接没提服务关闭所有资源通道、生产者、消费者
this.roomManager.remove(this);
this.clients.values().forEach(ClientWrapper::close);
EventPublisher.publishEvent(new RoomCloseEvent(this));
}
@Override
public void remove() {
log.info("移除房间:{}", this.roomId);
this.roomManager.remove(this);
}
/**

View File

@@ -78,7 +78,7 @@ public class Transport implements Closeable {
@Override
public void close() {
// TODO发送事件
// TODO实现
}
}

View File

@@ -1,11 +0,0 @@
package com.acgist.taoyao.signal.protocol;
/**
* 控制信令
* 直接通过平台发出控制信令
*
* @author acgist
*/
public interface ControlProtocol {
}

View File

@@ -14,7 +14,7 @@ import com.acgist.taoyao.signal.client.ClientType;
*
* @author acgist
*/
public class ProtocolControlAdapter extends ProtocolClientAdapter {
public abstract class ProtocolControlAdapter extends ProtocolClientAdapter {
protected ProtocolControlAdapter(String name, String signal) {
super(name, signal);

View File

@@ -2,7 +2,6 @@ package com.acgist.taoyao.signal.protocol.client;
import com.acgist.taoyao.boot.annotation.Description;
import com.acgist.taoyao.boot.annotation.Protocol;
import com.acgist.taoyao.signal.protocol.ControlProtocol;
import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
/**
@@ -14,7 +13,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
@Description(
flow = "信令服务->终端"
)
public class ClientRebootProtocol extends ProtocolClientAdapter implements ControlProtocol {
public class ClientRebootProtocol extends ProtocolClientAdapter {
public static final String SIGNAL = "client::reboot";

View File

@@ -2,7 +2,6 @@ package com.acgist.taoyao.signal.protocol.client;
import com.acgist.taoyao.boot.annotation.Description;
import com.acgist.taoyao.boot.annotation.Protocol;
import com.acgist.taoyao.signal.protocol.ControlProtocol;
import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
/**
@@ -14,7 +13,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
@Description(
flow = "信令服务->终端"
)
public class ClientShutdownProtocol extends ProtocolClientAdapter implements ControlProtocol {
public class ClientShutdownProtocol extends ProtocolClientAdapter {
public static final String SIGNAL = "client::shutdown";

View File

@@ -1,7 +1,14 @@
package com.acgist.taoyao.signal.protocol.control;
import java.util.Map;
import com.acgist.taoyao.boot.annotation.Description;
import com.acgist.taoyao.boot.annotation.Protocol;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.config.camera.BeautyProperties;
import com.acgist.taoyao.signal.protocol.ProtocolControlAdapter;
/**
* 打开美颜信令
@@ -10,7 +17,38 @@ import com.acgist.taoyao.boot.annotation.Protocol;
*/
@Protocol
@Description(
body = """
{
"to": "目标终端ID",
...BeautyProperties
}
""",
flow = {
"信令服务->终端",
"终端=>信令服务->终端"
}
)
public class ControlBeautyProtocol {
public class ControlBeautyProtocol extends ProtocolControlAdapter {
public static final String SIGNAL = "control::beauty";
public ControlBeautyProtocol() {
super("打开美颜信令", SIGNAL);
}
@Override
public void execute(String clientId, ClientType clientType, Client client, Client targetClient, Message message, Map<String, Object> body) {
client.push(targetClient.request(message));
}
/**
* @param clientId 终端ID
* @param beautyProperties 美颜配置
*
* @return 执行结果
*/
public Message execute(String clientId, BeautyProperties beautyProperties) {
return this.request(clientId, this.build(beautyProperties));
}
}

View File

@@ -20,7 +20,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolControlAdapter;
body = """
{
"to": "目标终端ID",
"active": 是否响铃true|false
"enabled": 是否响铃true|false
}
""",
flow = {
@@ -43,12 +43,12 @@ public class ControlBellProtocol extends ProtocolControlAdapter {
/**
* @param clientId 终端ID
* @param active 操作
* @param enabled 状态
*
* @return 执行结果
*/
public Message execute(String clientId, Boolean active) {
return this.request(clientId, this.build(Map.of(Constant.ACTIVE, active)));
public Message execute(String clientId, Boolean enabled) {
return this.request(clientId, this.build(Map.of(Constant.ENABLED, enabled)));
}
}

View File

@@ -1,10 +1,55 @@
package com.acgist.taoyao.signal.protocol.control;
import java.util.Map;
import com.acgist.taoyao.boot.annotation.Description;
import com.acgist.taoyao.boot.annotation.Protocol;
import com.acgist.taoyao.boot.config.MediaAudioProperties;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.protocol.ProtocolControlAdapter;
/**
* 配置音频
* 配置音频信令
*
* @author acgist
*/
public class ControlConfigAudioProtocol {
@Protocol
@Description(
memo = "如果没有指定参数使用默认参数配置",
body = """
{
"to": "目标终端ID",
...MediaAudioProperties
}
""",
flow = {
"信令服务->终端",
"终端=>信令服务->终端"
}
)
public class ControlConfigAudioProtocol extends ProtocolControlAdapter {
public static final String SIGNAL = "control::config::audio";
public ControlConfigAudioProtocol() {
super("配置音频信令", SIGNAL);
}
@Override
public void execute(String clientId, ClientType clientType, Client client, Client targetClient, Message message, Map<String, Object> body) {
client.push(targetClient.request(message));
}
/**
* @param clientId 终端ID
* @param mediaAudioProperties 音频配置
*
* @return 执行结果
*/
public Message execute(String clientId, MediaAudioProperties mediaAudioProperties) {
return this.request(clientId, this.build(mediaAudioProperties));
}
}

View File

@@ -1,10 +1,55 @@
package com.acgist.taoyao.signal.protocol.control;
import java.util.Map;
import com.acgist.taoyao.boot.annotation.Description;
import com.acgist.taoyao.boot.annotation.Protocol;
import com.acgist.taoyao.boot.config.MediaVideoProperties;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.protocol.ProtocolControlAdapter;
/**
* 配置视频
* 配置视频信令
*
* @author acgist
*/
public class ControlConfigVideoProtocol {
@Protocol
@Description(
memo = "如果没有指定参数使用默认参数配置",
body = """
{
"to": "目标终端ID",
...MediaVideoProperties
}
""",
flow = {
"信令服务->终端",
"终端=>信令服务->终端"
}
)
public class ControlConfigVideoProtocol extends ProtocolControlAdapter {
public static final String SIGNAL = "control::config::video";
public ControlConfigVideoProtocol() {
super("配置视频信令", SIGNAL);
}
@Override
public void execute(String clientId, ClientType clientType, Client client, Client targetClient, Message message, Map<String, Object> body) {
client.push(targetClient.request(message));
}
/**
* @param clientId 终端ID
* @param mediaVideoProperties 视频配置
*
* @return 执行结果
*/
public Message execute(String clientId, MediaVideoProperties mediaVideoProperties) {
return this.request(clientId, this.build(mediaVideoProperties));
}
}

View File

@@ -20,7 +20,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolControlAdapter;
body = """
{
"to": "目标终端ID",
"active": 是否录像true|false
"enabled": 是否录像true|false
}
""",
flow = {
@@ -42,13 +42,13 @@ public class ControlRecordProtocol extends ProtocolControlAdapter {
}
/**
* @param clientId 终端标识
* @param active 操作
* @param clientId 终端ID
* @param enabled 状态
*
* @return 执行结果
*/
public Message execute(String clientId, Boolean active) {
return this.request(clientId, this.build(Map.of(Constant.ACTIVE, active)));
public Message execute(String clientId, Boolean enabled) {
return this.request(clientId, this.build(Map.of(Constant.ENABLED, enabled)));
}
}

View File

@@ -1,16 +1,55 @@
package com.acgist.taoyao.signal.protocol.control;
import java.util.Map;
import com.acgist.taoyao.boot.annotation.Description;
import com.acgist.taoyao.boot.annotation.Protocol;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.config.camera.WatermarkProperties;
import com.acgist.taoyao.signal.protocol.ProtocolControlAdapter;
/**
* 打开水印信令
* 配置水印信令
*
* @author acgist
*/
@Protocol
@Description(
memo = "如果没有指定参数使用默认参数配置",
body = """
{
"to": "目标终端ID",
...WatermarkProperties
}
""",
flow = {
"信令服务->终端",
"终端=>信令服务->终端"
}
)
public class ControlWatermarkProtocol {
public class ControlWatermarkProtocol extends ProtocolControlAdapter {
public static final String SIGNAL = "control::watermark";
public ControlWatermarkProtocol() {
super("配置水印信令", SIGNAL);
}
@Override
public void execute(String clientId, ClientType clientType, Client client, Client targetClient, Message message, Map<String, Object> body) {
client.push(targetClient.request(message));
}
/**
* @param clientId 终端ID
* @param watermarkProperties 水印配置
*
* @return 执行结果
*/
public Message execute(String clientId, WatermarkProperties watermarkProperties) {
return this.request(clientId, this.build(watermarkProperties));
}
}

View File

@@ -17,15 +17,12 @@ import com.acgist.taoyao.signal.party.media.Consumer;
import com.acgist.taoyao.signal.party.media.Room;
import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter;
import lombok.extern.slf4j.Slf4j;
/**
* 关闭消费者信令
* 注意:正常情况不会存在关闭消费者的情况,所以一般不用处理关闭消费者信令。
*
* @author acgist
*/
@Slf4j
@Protocol
@Description(
body = """
@@ -34,7 +31,10 @@ import lombok.extern.slf4j.Slf4j;
"consumerId": "消费者ID"
}
""",
flow = "终端->信令服务+)终端"
flow = {
"媒体服务->信令服务-)终端",
"终端->信令服务->媒体服务->信令服务+)终端"
}
)
public class MediaConsumerCloseProtocol extends ProtocolRoomAdapter implements ApplicationListener<MediaConsumerCloseEvent> {
@@ -48,21 +48,25 @@ public class MediaConsumerCloseProtocol extends ProtocolRoomAdapter implements A
@Override
public void onApplicationEvent(MediaConsumerCloseEvent event) {
final Room room = event.getRoom();
final Client mediaClient = event.getMediaClient();
final Map<String, Object> body = Map.of(
Constant.ROOM_ID, room.getRoomId(),
Constant.CONSUMER_ID, event.getConsumerId()
);
room.broadcastAll(this.build(body));
mediaClient.push(this.build(body));
}
@Override
public void execute(String clientId, ClientType clientType, Room room, Client client, Client mediaClient, Message message, Map<String, Object> body) {
final String consumerId = MapUtils.get(body, Constant.CONSUMER_ID);
final Consumer consumer = room.consumer(consumerId);
if(consumer == null) {
log.debug("关闭消费者无效:{}", consumerId);
} else {
if(clientType.mediaClient()) {
consumer.close();
} else if(clientType.mediaServer()) {
consumer.remove();
room.broadcast(message);
} else {
this.logNoAdapter(clientType);
}
}

View File

@@ -8,7 +8,6 @@ import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.boot.utils.ScriptUtils;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.protocol.ControlProtocol;
import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
import lombok.extern.slf4j.Slf4j;
@@ -25,7 +24,7 @@ import lombok.extern.slf4j.Slf4j;
"终端->信令服务+)终端"
}
)
public class PlatformRebootProtocol extends ProtocolClientAdapter implements ControlProtocol {
public class PlatformRebootProtocol extends ProtocolClientAdapter {
public static final String SIGNAL = "platform::reboot";

View File

@@ -10,7 +10,6 @@ import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.boot.utils.ScriptUtils;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.protocol.ControlProtocol;
import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
import lombok.extern.slf4j.Slf4j;
@@ -27,7 +26,7 @@ import lombok.extern.slf4j.Slf4j;
"终端->信令服务+)终端"
}
)
public class PlatformShutdownProtocol extends ProtocolClientAdapter implements ControlProtocol {
public class PlatformShutdownProtocol extends ProtocolClientAdapter {
public static final String SIGNAL = "platform::shutdown";

View File

@@ -2,12 +2,15 @@ package com.acgist.taoyao.signal.protocol.room;
import java.util.Map;
import org.springframework.context.ApplicationListener;
import com.acgist.taoyao.boot.annotation.Description;
import com.acgist.taoyao.boot.annotation.Protocol;
import com.acgist.taoyao.boot.config.Constant;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.event.room.RoomCloseEvent;
import com.acgist.taoyao.signal.party.media.Room;
import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter;
@@ -25,21 +28,28 @@ import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter;
""",
flow = "终端->信令服务+)终端"
)
public class RoomCloseProtocol extends ProtocolRoomAdapter {
public class RoomCloseProtocol extends ProtocolRoomAdapter implements ApplicationListener<RoomCloseEvent> {
private static final String SIGNAL = "room::close";
public RoomCloseProtocol() {
super("关闭房间信令", SIGNAL);
}
@Override
public void onApplicationEvent(RoomCloseEvent event) {
final Room room = event.getRoom();
final Client mediaClient = room.getMediaClient();
final Map<String, String> body = Map.of(Constant.ROOM_ID, room.getRoomId());
mediaClient.push(this.build(body));
}
@Override
public void execute(String clientId, ClientType clientType, Room room, Client client, Client mediaClient, Message message, Map<String, Object> body) {
// TODO改为星型
if(clientType.web()) {
mediaClient.push(this.build(Map.of(Constant.ROOM_ID, room.getRoomId())));
} else if(clientType.mediaServer()) {
if(clientType.mediaClient()) {
room.close();
} else if(clientType.mediaServer()) {
room.remove();
room.broadcast(message);
} else {
this.logNoAdapter(clientType);

View File

@@ -8,7 +8,6 @@ import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.boot.utils.ScriptUtils;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.protocol.ControlProtocol;
import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
import lombok.extern.slf4j.Slf4j;
@@ -25,7 +24,7 @@ import lombok.extern.slf4j.Slf4j;
"终端->信令服务+)终端"
}
)
public class SystemRebootProtocol extends ProtocolClientAdapter implements ControlProtocol {
public class SystemRebootProtocol extends ProtocolClientAdapter {
public static final String SIGNAL = "system::reboot";

View File

@@ -8,7 +8,6 @@ import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.boot.utils.ScriptUtils;
import com.acgist.taoyao.signal.client.Client;
import com.acgist.taoyao.signal.client.ClientType;
import com.acgist.taoyao.signal.protocol.ControlProtocol;
import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
import lombok.extern.slf4j.Slf4j;
@@ -25,7 +24,7 @@ import lombok.extern.slf4j.Slf4j;
"终端->信令服务+)终端"
}
)
public class SystemShutdownProtocol extends ProtocolClientAdapter implements ControlProtocol {
public class SystemShutdownProtocol extends ProtocolClientAdapter {
public static final String SIGNAL = "system::shutdown";