Поток Peerjs дублируется (отправляется два или более раз) и иногда не показывает никакого потока

#javascript #node.js #vue.js #socket.io #webrtc

Вопрос:

Я пытаюсь создать приложение для видеочата с помощью Express, сокета.IO, PeerJS, Vue3 и Ionic. У меня возникли проблемы с отправкой потока одноранговым узлам, так как он отправляется два раза, иногда больше, а иногда он задерживается без отправки каких-либо потоков, но показывает соединение в cli peerjs.

Vue (Код на стороне клиента):

 <template>
  <ion-page>
    <ion-header :translucent="true">
      <ion-toolbar>
        <ion-title>Chat</ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content :fullscreen="true">
      <ion-header collapse="condense">
        <ion-toolbar>
          <ion-title size="large">Chat</ion-title>
        </ion-toolbar>
      </ion-header>
      <ion-grid>
        <ion-row class="ion-justify-content-center">
          <ion-col>
            <VideoStream
              v-if="webCamVideoReady amp;amp; webCamStream"
              :stream="webCamStream"
            />
          </ion-col>
        </ion-row>
        <ion-row>
          <ion-col v-for="(stream, i) in usersVideoStreams" :key="i">
            <VideoStream :stream="stream" />
          </ion-col>
        </ion-row>
      </ion-grid>
    </ion-content>
  </ion-page>
</template>

<script>
import {
  IonContent,
  IonHeader,
  IonList,
  IonPage,
  IonRefresher,
  IonRefresherContent,
  IonTitle,
  IonToolbar,
  IonGrid,
  IonRow,
  IonCol
} from "@ionic/vue";
import VideoStream from "@/components/VideoStream";
import io from "socket.io-client";
import Peer from "peerjs";
import { baseURL } from "../main";
import { ref, onMounted } from "vue";

export default {
  name: "Chat",
  components: {
    IonContent,
    IonHeader,
    IonList,
    IonPage,
    IonRefresher,
    IonRefresherContent,
    IonTitle,
    IonToolbar,
    IonGrid,
    IonRow,
    IonCol,
    VideoStream
  },
  props: ["roomId"],
  setup({ roomId }) {
    const socket = io(baseURL);
    const peer = new Peer(undefined, {
      host: "/",
      port: 4000
    });

    const webCamStream = ref(null);
    const webCamVideoReady = ref(false);
    const usersVideoStreams = ref([]);

    onMounted(() => {
      navigator.mediaDevices
        .getUserMedia({
          video: true,
          audio: true
        })
        .then(stream => {
          webCamStream.value = stream;
          webCamVideoReady.value = true;

          peer.on("call", call => {
            call.answer(stream);

            call.on("stream", userVideoStream => {
              usersVideoStreams.value.push(userVideoStream);
            });
          });

          socket.on("user-connected", userId => {
            const call = peer.call(userId, stream);

            call.on("stream", userVideoStream => {
              usersVideoStreams.value.push(userVideoStream);
            });

            // call.on("close", () => {});
          });
        });
    });

    peer.on("open", id => {
      socket.emit("join-room", roomId, id);
    });

    return { webCamVideoReady, webCamStream, usersVideoStreams };
  }
};
</script>
 

Компонент Vue видеопотока:

 <template>
  <video
    ref="webCamVideo"
    @loadedmetadata="webCamVideo.play()"
    muted
    oncontextmenu="return false;"
  ></video>
</template>

<script>
import { onMounted, ref, watch, watchEffect } from "vue";
export default {
  name: "VideoStream",
  props: ["stream"],
  setup(props) {
    const webCamVideo = ref(null);

    onMounted(() => {
      webCamVideo.value.srcObject = props.stream;
    });

    return { webCamVideo };
  }
};
</script>

 

Одноранговое и сокетное соединение:

 const socket = io(baseURL);

const peer = new Peer(undefined, {
  host: "/",
  port: 4000
});
 

Запуск Peerjs с помощью команды

peerjs —порт 4000

Node.js Сокет На Стороне Сервера.Код ввода-вывода

 const io = require("socket.io")();

io.on("connection", socket => {
  socket.on("join-room", (roomId, userId) => {
    console.log(roomId, userId);
    socket.join(roomId);
    socket.broadcast.to(roomId).emit("user-connected", userId);
  });
});

module.exports = { io };

 

Комментарии:

1. возможно, придется что-то сделать с этим событием, вызываемым в разных событиях, которые могут быть вызваны одним и тем же вызовом клиента.on(«поток», userVideoStream => { usersVideoStreams.value.push(userVideoStream); });