WebRT C Asyn c вызовы на стороне сервера (Dynami c серверы ICE) - PullRequest
0 голосов
/ 04 августа 2020

Я пытаюсь реализовать службу 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% людей этот следующий код работает. Их всего несколько.

...