#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); });