Я пытаюсь реализовать службу WebRT C с динамическими c серверами ICE на стороне сервера.
Мой код на стороне сервера, когда кто-то присоединяется к комнате, выглядит следующим образом:
socket.on("video_join", async (data) => {
let token = data.token;
let room = rooms[token];
let user = {
id: socket.id,
name: data.name
};
let iceServers = await getICEServers();
if (!iceServers) {
io.to(socket.id).emit("video_error");
return;
}
if (rooms[token]) {
rooms[token].users.push(user);
} else {
rooms[token] = {
users: [user]
};
}
socketToRoom[socket.id] = token;
io.to(socket.id).emit("video_joined");
rooms[token].users.map((user: any) => {
if (user.id !== socket.id)
io.to(user.id).emit("video_users", {
peers: rooms[token].users,
iceServers,
});
});
});
Как вы можете заметить, ICEServer - это асинхронные c функции, которые я жду.
В интерфейсе все выглядит так:
this.io.on("video_users", (data: any) => {
data.peers.map((peer: any) => {
if (!this.peers[peer.id] && peer.id !== this.state.id) {
this.peers[peer.id] = this.generatePeer(
peer.id,
true,
data.iceServers
);
}
});
});
Что в основном генерирует партнер-инициатор:
generatePeer(id: string, initiator: boolean = false, iceServers: any = null) {
if (!iceServers) return null;
let peer = new Peer({
initiator: initiator,
trickle: false,
config: {
iceServers: iceServers
},
stream: this.state.stream
});
peer.on("signal", (data: any) => {
if (this.state.id !== id) {
this.io.emit("video_signal", {
signal: data,
to: id,
name: this.state.name,
iceServers: iceServers
});
}
});
//...Some more irrelevant code
}
И, наконец, по сигналу:
this.io.on("video_new_signal", async (data: any) => {
let id = data.from;
if (id !== this.state.id) {
if (!this.peers[id]) {
this.peers[id] = this.generatePeer(id, false, data.iceServers);
}
this.peers[id].signal(data.signal);
}
});
Теперь проблема в том, что некоторые пользователи (на самом деле некоторые) получают Ice connection failed
или Transport channel closed
или даже Failed to execute 'setRemoteDescription' on 'RTCPeerConnection': Failed to set remote answer sdp: Called in wrong state: kStable
.
Я сузил круг вопросов и считаю, что именно это асинхронное c поведение может вызывать какой-то неправильный порядок событий при подключении. Я не могу понять, почему и что именно, но есть ли способ использовать эти динамические c iceServers
? Срок их действия истекает через 120 секунд, поэтому каждая строка действительно уникальна. Как я уже упоминал - для 99,9% людей этот следующий код работает. Их всего несколько.