[*] 资源释放优化

This commit is contained in:
acgist
2023-04-30 13:42:58 +08:00
parent 165655c4e6
commit d9915e3013
6 changed files with 106 additions and 66 deletions

View File

@@ -16,7 +16,7 @@
> 注意删除目录`linux-include/build`和`linux-include/third_party`目录中除了`abseil-cpp`以外的所有依赖(当然不删也没关系就是文件太多编译器会变慢) > 注意删除目录`linux-include/build`和`linux-include/third_party`目录中除了`abseil-cpp`以外的所有依赖(当然不删也没关系就是文件太多编译器会变慢)
## 镜头旋转 ## 视频旋转
1. 应用旋转(横屏|竖屏) 1. 应用旋转(横屏|竖屏)
2. 代码旋转 2. 代码旋转

View File

@@ -91,7 +91,7 @@ const signalChannel = {
clearTimeout(me.heartbeatTimer); clearTimeout(me.heartbeatTimer);
} }
me.heartbeatTimer = setTimeout(async function () { me.heartbeatTimer = setTimeout(async function () {
if (me.channel && me.channel.readyState === WebSocket.OPEN) { if (me.connected()) {
me.push( me.push(
// TODO电池信息 // TODO电池信息
protocol.buildMessage("client::heartbeat", { protocol.buildMessage("client::heartbeat", {
@@ -115,7 +115,7 @@ const signalChannel = {
*/ */
async connect(address, reconnection = true) { async connect(address, reconnection = true) {
const me = this; const me = this;
if (me.channel && me.channel.readyState === WebSocket.OPEN) { if (me.connected()) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
resolve(me.channel); resolve(me.channel);
}); });
@@ -147,7 +147,7 @@ const signalChannel = {
me.channel.on("close", async function () { me.channel.on("close", async function () {
console.warn("信令通道关闭:", me.address); console.warn("信令通道关闭:", me.address);
me.taoyao.connect = false; me.taoyao.connect = false;
if(me.channel && me.channel.readyState !== WebSocket.OPEN) { if(!me.connected()) {
me.taoyao.closeAllRoom(); me.taoyao.closeAllRoom();
} }
if (me.reconnection) { if (me.reconnection) {
@@ -157,13 +157,6 @@ const signalChannel = {
}); });
me.channel.on("error", async function (e) { me.channel.on("error", async function (e) {
console.error("信令通道异常:", me.address, e); console.error("信令通道异常:", me.address, e);
me.taoyao.connect = false;
if(me.channel && me.channel.readyState !== WebSocket.OPEN) {
me.taoyao.closeAllRoom();
}
if (me.reconnection) {
me.reconnect();
}
// 不要失败回调 // 不要失败回调
}); });
me.channel.on("message", async function (data) { me.channel.on("message", async function (data) {
@@ -177,14 +170,22 @@ const signalChannel = {
}); });
}); });
}, },
/**
* @returns 是否连接成功
*/
connected() {
const me = this;
return me.channel && me.channel.readyState === WebSocket.OPEN;
},
/** /**
* 重连 * 重连
*/ */
reconnect() { reconnect() {
const me = this; const me = this;
if ( if (
me.lockReconnect || me.lockReconnect ||
(me.channel && me.channel.readyState === WebSocket.OPEN) me.taoyao.connect ||
me.connected()
) { ) {
return; return;
} }
@@ -551,7 +552,7 @@ class Taoyao {
} }
closeAllRoom() { closeAllRoom() {
console.info("关闭所有房间"); console.info("关闭所有房间", this.rooms.size());
this.rooms.forEach((room, roomId) => { this.rooms.forEach((room, roomId) => {
room.closeAll(); room.closeAll();
}); });

View File

@@ -96,7 +96,7 @@ const signalChannel = {
clearTimeout(me.heartbeatTimer); clearTimeout(me.heartbeatTimer);
} }
me.heartbeatTimer = setTimeout(async function () { me.heartbeatTimer = setTimeout(async function () {
if (me.channel && me.channel.readyState === WebSocket.OPEN) { if (me.connected()) {
const battery = await navigator.getBattery(); const battery = await navigator.getBattery();
me.push( me.push(
protocol.buildMessage("client::heartbeat", { protocol.buildMessage("client::heartbeat", {
@@ -110,6 +110,13 @@ const signalChannel = {
} }
}, me.heartbeatTime); }, me.heartbeatTime);
}, },
/**
* @returns 是否连接成功
*/
connected() {
const me = this;
return me.channel && me.channel.readyState === WebSocket.OPEN;
},
/** /**
* 连接 * 连接
* *
@@ -120,7 +127,7 @@ const signalChannel = {
*/ */
async connect(address, reconnection = true) { async connect(address, reconnection = true) {
const me = this; const me = this;
if (me.channel && me.channel.readyState === WebSocket.OPEN) { if (me.connected()) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
resolve(me.channel); resolve(me.channel);
}); });
@@ -152,7 +159,7 @@ const signalChannel = {
me.channel.onclose = async function () { me.channel.onclose = async function () {
console.warn("信令通道关闭:", me.channel); console.warn("信令通道关闭:", me.channel);
me.taoyao.connect = false; me.taoyao.connect = false;
if(me.channel && me.channel.readyState !== WebSocket.OPEN) { if(!me.connected()) {
me.taoyao.closeRoomMedia(); me.taoyao.closeRoomMedia();
me.taoyao.closeSessionMedia(); me.taoyao.closeSessionMedia();
} }
@@ -163,14 +170,6 @@ const signalChannel = {
}; };
me.channel.onerror = async function (e) { me.channel.onerror = async function (e) {
console.error("信令通道异常:", me.channel, e); console.error("信令通道异常:", me.channel, e);
me.taoyao.connect = false;
if(me.channel && me.channel.readyState !== WebSocket.OPEN) {
me.taoyao.closeRoomMedia();
me.taoyao.closeSessionMedia();
}
if (me.reconnection) {
me.reconnect();
}
// 不要失败回调 // 不要失败回调
}; };
me.channel.onmessage = async function (e) { me.channel.onmessage = async function (e) {
@@ -189,8 +188,9 @@ const signalChannel = {
reconnect() { reconnect() {
const me = this; const me = this;
if ( if (
me.lockReconnect || me.lockReconnect ||
(me.channel && me.channel.readyState === WebSocket.OPEN) me.taoyao.connect ||
me.connected()
) { ) {
return; return;
} }
@@ -333,10 +333,15 @@ class Session {
this.remoteAudioEnabled = false; this.remoteAudioEnabled = false;
this.remoteVideoEnabled = false; this.remoteVideoEnabled = false;
this.localAudioTrack.stop(); this.localAudioTrack.stop();
this.localAudioTrack = null;
this.localVideoTrack.stop(); this.localVideoTrack.stop();
this.localVideoTrack = null;
this.remoteAudioTrack.stop(); this.remoteAudioTrack.stop();
this.remoteAudioTrack = null;
this.remoteVideoTrack.stop(); this.remoteVideoTrack.stop();
this.remoteVideoTrack = null;
this.peerConnection.close(); this.peerConnection.close();
this.peerConnection = null;
} }
async addIceCandidate(candidate) { async addIceCandidate(candidate) {
@@ -396,12 +401,24 @@ class RemoteClient {
this.volume = ((volume + 127) / 127 * 100) + "%"; this.volume = ((volume + 127) / 127 * 100) + "%";
} }
close() {
if(this.audioTrack) {
this.audioTrack.stop();
this.audioTrack = null;
}
if(this.videoTrack) {
this.videoTrack.stop();
this.videoTrack = null;
}
}
} }
/** /**
* 桃夭 * 桃夭
*/ */
class Taoyao extends RemoteClient { class Taoyao extends RemoteClient {
// 信令连接 // 信令连接
connect = false; connect = false;
// 信令地址 // 信令地址
@@ -963,7 +980,7 @@ class Taoyao extends RemoteClient {
const { roomId, consumerId } = message.body; const { roomId, consumerId } = message.body;
const consumer = me.consumers.get(consumerId); const consumer = me.consumers.get(consumerId);
if (consumer) { if (consumer) {
console.info("关闭消费者:", consumerId); console.debug("关闭消费者:", consumerId);
consumer.close(); consumer.close();
me.consumers.delete(consumerId); me.consumers.delete(consumerId);
} else { } else {
@@ -1067,7 +1084,7 @@ class Taoyao extends RemoteClient {
const { roomId, consumerId } = message.body; const { roomId, consumerId } = message.body;
const consumer = me.consumers.get(consumerId); const consumer = me.consumers.get(consumerId);
if (consumer) { if (consumer) {
console.info("恢复消费者:", consumerId); console.debug("恢复消费者:", consumerId);
consumer.resume(); consumer.resume();
} else { } else {
console.debug("恢复消费者无效:", consumerId); console.debug("恢复消费者无效:", consumerId);
@@ -1149,7 +1166,7 @@ class Taoyao extends RemoteClient {
const { roomId, producerId } = message.body; const { roomId, producerId } = message.body;
const producer = me.dataProducer; const producer = me.dataProducer;
if (producer) { if (producer) {
console.info("关闭数据生产者:", producerId); console.debug("关闭数据生产者:", producerId);
producer.close(); producer.close();
// TODO类型判断设置为空 // TODO类型判断设置为空
} else { } else {
@@ -1174,7 +1191,7 @@ class Taoyao extends RemoteClient {
const { roomId, producerId } = message.body; const { roomId, producerId } = message.body;
const producer = me.getProducer(producerId); const producer = me.getProducer(producerId);
if (producer) { if (producer) {
console.info("关闭生产者:", producerId); console.debug("关闭生产者:", producerId);
producer.close(); producer.close();
// TODO类型判断设置为空 // TODO类型判断设置为空
} else { } else {
@@ -1488,8 +1505,6 @@ class Taoyao extends RemoteClient {
} }
console.info("关闭房间:", roomId); console.info("关闭房间:", roomId);
me.closeRoomMedia(); me.closeRoomMedia();
me.roomId = null;
me.remoteClients.clear();
} }
/** /**
* 创建房间信令 * 创建房间信令
@@ -1527,9 +1542,10 @@ class Taoyao extends RemoteClient {
roomId: me.roomId, roomId: me.roomId,
}) })
); );
if(!response.success) { if(response.code !== '0000') {
// TODO提示 // TODO提示
return; me.roomId = null;
return;
} }
const routerRtpCapabilities = response.body.rtpCapabilities; const routerRtpCapabilities = response.body.rtpCapabilities;
me.mediasoupDevice = new mediasoupClient.Device(); me.mediasoupDevice = new mediasoupClient.Device();
@@ -1631,8 +1647,6 @@ class Taoyao extends RemoteClient {
roomId: me.roomId roomId: me.roomId
})); }));
me.closeRoomMedia(); me.closeRoomMedia();
me.roomId = null;
me.remoteClients.clear();
} }
/** /**
* 离开房间信令 * 离开房间信令
@@ -1702,19 +1716,16 @@ class Taoyao extends RemoteClient {
} }
// 检查设备 // 检查设备
self.checkDevice(); self.checkDevice();
// 释放资源
self.closeRoomMedia();
/** /**
* 解决浏览器的自动播放策略问题 * 解决浏览器的自动播放策略问题
*/ */
// TODO完全关闭以后释放资源 // {
{ // const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); // stream.getAudioTracks().forEach((audioTrack) => {
stream.getAudioTracks().forEach((audioTrack) => { // audioTrack.enabled = false;
audioTrack.enabled = false; // setTimeout(() => audioTrack.stop(), 30000);
setTimeout(() => audioTrack.stop(), 30000); // });
}); // }
}
// TODO代码提取 // TODO代码提取
if (self.dataProduce || self.audioProduce || self.videoProduce) { if (self.dataProduce || self.audioProduce || self.videoProduce) {
const response = await self.request( const response = await self.request(
@@ -2389,33 +2400,48 @@ class Taoyao extends RemoteClient {
* 关闭视频房间媒体 * 关闭视频房间媒体
*/ */
closeRoomMedia() { closeRoomMedia() {
console.info("关闭视频房间媒体"); console.debug("关闭视频房间媒体");
let me = this; const me = this;
if(me.audioTrack) { me.roomId = null;
me.audioTrack.stop(); me.close();
}
if(me.videoTrack) {
me.videoTrack.stop();
}
if (me.sendTransport) { if (me.sendTransport) {
me.sendTransport.close(); me.sendTransport.close();
me.sendTransport = null;
} }
if (me.recvTransport) { if (me.recvTransport) {
me.recvTransport.close(); me.recvTransport.close();
me.recvTransport = null;
} }
me.sendTransport = null; if(me.dataProducer) {
me.recvTransport = null; me.dataProducer.close();
me.dataProducer = null; me.dataProducer = null;
me.audioProducer = null; }
me.videoProducer = null; if(me.audioProducer) {
me.audioProducer.close();
me.audioProducer = null;
}
if(me.videoProducer) {
me.videoProducer.close();
me.videoProducer = null;
}
me.consumers.forEach((consumer, consumerId) => {
consumer.close();
});
me.consumers.clear(); me.consumers.clear();
me.dataConsumers.forEach((dataConsumer, consumerId) => {
dataConsumer.close();
});
me.dataConsumers.clear(); me.dataConsumers.clear();
me.remoteClients.forEach((client, clientId) => {
client.close();
});
me.remoteClients.clear();
} }
/** /**
* 关闭视频会话媒体 * 关闭视频会话媒体
*/ */
closeSessionMedia() { closeSessionMedia() {
console.info("关闭视频会话媒体"); console.debug("关闭视频会话媒体");
const me = this; const me = this;
me.sessionClients.forEach((session, sessionId) => { me.sessionClients.forEach((session, sessionId) => {
if(session) { if(session) {
@@ -2429,8 +2455,8 @@ class Taoyao extends RemoteClient {
/** /**
* 关闭资源 * 关闭资源
*/ */
close() { closeAll() {
let me = this; const me = this;
me.closeRoomMedia(); me.closeRoomMedia();
me.closeSessionMedia(); me.closeSessionMedia();
if (me.signalChannel) { if (me.signalChannel) {

View File

@@ -1,5 +1,7 @@
package com.acgist.taoyao.signal.client; package com.acgist.taoyao.signal.client;
import java.util.stream.Stream;
import com.acgist.taoyao.boot.model.MessageCodeException; import com.acgist.taoyao.boot.model.MessageCodeException;
import lombok.Getter; import lombok.Getter;
@@ -55,4 +57,13 @@ public enum ClientType {
throw MessageCodeException.of("未知终端类型:" + value); throw MessageCodeException.of("未知终端类型:" + value);
} }
/**
* 媒体终端
*/
public static final ClientType[] MEDIA_CLIENT = Stream.of(ClientType.values()).filter(ClientType::mediaClient).toArray(ClientType[]::new);
/**
* 媒体服务
*/
public static final ClientType[] MEDIA_SERVER = Stream.of(ClientType.values()).filter(ClientType::mediaServer).toArray(ClientType[]::new);
} }

View File

@@ -103,6 +103,7 @@ public class RoomManager {
// mediaClient.request(clone); // mediaClient.request(clone);
// 更新媒体服务 // 更新媒体服务
room.setMediaClient(mediaClient); room.setMediaClient(mediaClient);
// TODO通知重建房间
}); });
} }

View File

@@ -66,7 +66,8 @@ public class RoomCreateProtocol extends ProtocolClientAdapter implements Applica
message.cloneWithoutBody() message.cloneWithoutBody()
); );
message.setBody(room.getRoomStatus()); message.setBody(room.getRoomStatus());
this.clientManager.broadcast(message); // 通知媒体终端
this.clientManager.broadcast(message, ClientType.MEDIA_CLIENT);
} else { } else {
this.logNoAdapter(clientType); this.logNoAdapter(clientType);
} }