[*] 资源释放优化

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`以外的所有依赖(当然不删也没关系就是文件太多编译器会变慢)
## 镜头旋转
## 视频旋转
1. 应用旋转(横屏|竖屏)
2. 代码旋转

View File

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

View File

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

View File

@@ -1,5 +1,7 @@
package com.acgist.taoyao.signal.client;
import java.util.stream.Stream;
import com.acgist.taoyao.boot.model.MessageCodeException;
import lombok.Getter;
@@ -55,4 +57,13 @@ public enum ClientType {
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);
// 更新媒体服务
room.setMediaClient(mediaClient);
// TODO通知重建房间
});
}

View File

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