[*] 资源释放优化
This commit is contained in:
@@ -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. 代码旋转
|
||||||
|
|||||||
@@ -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();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ public class RoomManager {
|
|||||||
// mediaClient.request(clone);
|
// mediaClient.request(clone);
|
||||||
// 更新媒体服务
|
// 更新媒体服务
|
||||||
room.setMediaClient(mediaClient);
|
room.setMediaClient(mediaClient);
|
||||||
|
// TODO:通知重建房间
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user