fix: dplayer can not playing
This commit is contained in:
@@ -1,67 +1,93 @@
|
||||
import { userInfoStore } from "@/store/user";
|
||||
import axios from "axios";
|
||||
|
||||
const userinfo = userInfoStore();
|
||||
|
||||
|
||||
export const searchPlayRoom = async (inputValue: string) => {
|
||||
const response = await axios.post('/api/playroom/search',{
|
||||
r_name: inputValue
|
||||
},{
|
||||
headers:{
|
||||
'Authorization': "Bearer " + userinfo.token
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return response.data.data.records
|
||||
} else {
|
||||
console.error(response.data.msg)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export const createPlayroom = async (room_name: string) => {
|
||||
const response = await axios.post('/api/playroom/create',{
|
||||
r_name: room_name
|
||||
},{
|
||||
headers:{
|
||||
'Authorization': "Bearer " + userinfo.token
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
export const getPlayrooms = async ()=> {
|
||||
const response = await axios.get('/api/playroom/get',{
|
||||
headers:{
|
||||
'Authorization' : `Bearer ${userinfo.token}`
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return response.data.data;
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
export const joinPlayroom = async (r_id: number) => {
|
||||
const response = await axios.post('/api/inviting/playroom',{
|
||||
inviter: userinfo.user.id,
|
||||
target: userinfo.user.id,
|
||||
status: 0,
|
||||
room: r_id,
|
||||
},{
|
||||
headers:{
|
||||
'Authorization': "Bearer " + userinfo.token
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
import { userInfoStore } from "@/store/user";
|
||||
import axios from "axios";
|
||||
|
||||
const userinfo = userInfoStore();
|
||||
|
||||
|
||||
export const searchPlayRoom = async (inputValue: string) => {
|
||||
const response = await axios.post('/api/playroom/search',{
|
||||
r_name: inputValue
|
||||
},{
|
||||
headers:{
|
||||
'Authorization': "Bearer " + userinfo.token
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return response.data.data.records
|
||||
} else {
|
||||
console.error(response.data.msg)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export const createPlayroom = async (room_name: string) => {
|
||||
const response = await axios.post('/api/playroom/create',{
|
||||
r_name: room_name
|
||||
},{
|
||||
headers:{
|
||||
'Authorization': "Bearer " + userinfo.token
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
export const getPlayrooms = async ()=> {
|
||||
const response = await axios.get('/api/playroom/get',{
|
||||
headers:{
|
||||
'Authorization' : `Bearer ${userinfo.token}`
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return response.data.data;
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
export const joinPlayroom = async (r_id: number) => {
|
||||
const response = await axios.post('/api/inviting/playroom',{
|
||||
inviter: userinfo.user.id,
|
||||
target: userinfo.user.id,
|
||||
status: 0,
|
||||
room: r_id,
|
||||
},{
|
||||
headers:{
|
||||
'Authorization': "Bearer " + userinfo.token
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
export const getPlayroomDetails = async (r_id:number) =>{
|
||||
const response = await axios.get('/api/playroom/detail/'+r_id,{
|
||||
headers:{
|
||||
'Authorization': "Bearer " + userinfo.token
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return response.data.data;
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
export const getPlayroomMembers = async (r_id: number) => {
|
||||
const response = await axios.get('/api/playroom/member/'+r_id,{
|
||||
headers:{
|
||||
'Authorization': "Bearer " + userinfo.token
|
||||
}
|
||||
})
|
||||
if(response.data.code === "200"){
|
||||
return response.data.data;
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,37 @@
|
||||
@import './base.css';
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
/* margin: 0 auto; */
|
||||
/* padding: 2rem; */
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
a,
|
||||
.green {
|
||||
text-decoration: none;
|
||||
color: hsla(160, 100%, 37%, 1);
|
||||
transition: 0.4s;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
a:hover {
|
||||
/* background-color: hsla(160, 100%, 37%, 0.2); */
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
body {
|
||||
display: flex;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: grid;
|
||||
/* grid-template-columns: 1fr 1fr;
|
||||
padding: 0 2rem; */
|
||||
}
|
||||
}
|
||||
@import './base.css';
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* margin: 0 auto; */
|
||||
/* padding: 2rem; */
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
a,
|
||||
.green {
|
||||
text-decoration: none;
|
||||
color: hsla(160, 100%, 37%, 1);
|
||||
transition: 0.4s;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
a:hover {
|
||||
/* background-color: hsla(160, 100%, 37%, 0.2); */
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
body {
|
||||
display: flex;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: grid;
|
||||
/* grid-template-columns: 1fr 1fr;
|
||||
padding: 0 2rem; */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +1,92 @@
|
||||
import { ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import { connectWebSocket, disconnectWebSocket, sendMessage, setIsManualClose } from '@/websocket/roomSocket'
|
||||
|
||||
interface PlayroomState {
|
||||
id: number
|
||||
r_id: number;
|
||||
r_name: string;
|
||||
r_introduction: string;
|
||||
r_avatar: string;
|
||||
role: number;
|
||||
}
|
||||
|
||||
|
||||
export const PlayroomStore = defineStore("PlayroomStore",
|
||||
() =>{
|
||||
const currentPlayroom = ref<PlayroomState>();
|
||||
const currentUrl = ref<string>("");
|
||||
|
||||
const setCurrentPlayroom = (playroom: PlayroomState) => {
|
||||
currentPlayroom.value = playroom;
|
||||
}
|
||||
|
||||
const getCurrentPlayroom = () =>{
|
||||
return currentPlayroom.value;
|
||||
}
|
||||
|
||||
const getCurrentId = () =>{
|
||||
return currentPlayroom.value?.r_id;
|
||||
}
|
||||
|
||||
const setCurrentUrl = (url: string) => {
|
||||
currentUrl.value = url;
|
||||
}
|
||||
|
||||
const clearPlayroom = () => {
|
||||
currentPlayroom.value = undefined;
|
||||
currentUrl.value = "";
|
||||
}
|
||||
|
||||
return {
|
||||
getCurrentPlayroom,
|
||||
getCurrentId,
|
||||
setCurrentPlayroom,
|
||||
setCurrentUrl,
|
||||
clearPlayroom,
|
||||
}
|
||||
})
|
||||
|
||||
export const videoSocketStore = defineStore("videoSocketStore",{
|
||||
state: () => ({
|
||||
isConnected: false,
|
||||
hasGotMessage: false,
|
||||
id: 0
|
||||
}),
|
||||
|
||||
actions: {
|
||||
connect(id: number) {
|
||||
this.id = id;
|
||||
if (this.isConnected === true) return
|
||||
connectWebSocket();
|
||||
this.isConnected = true;
|
||||
},
|
||||
disconnect() {
|
||||
setIsManualClose(true);
|
||||
disconnectWebSocket();
|
||||
this.isConnected = false;
|
||||
},
|
||||
send(message: string) {
|
||||
sendMessage(JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
})
|
||||
import { ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import { connectWebSocket, disconnectWebSocket, sendMessage, setIsManualClose } from "@/websocket/roomSocket";
|
||||
|
||||
interface PlayroomState {
|
||||
id: number
|
||||
r_id: number;
|
||||
r_name: string;
|
||||
r_introduction: string;
|
||||
r_avatar: string;
|
||||
role: number;
|
||||
}
|
||||
|
||||
interface member {
|
||||
id: number;
|
||||
u_id: string;
|
||||
u_name: string;
|
||||
u_avatar: string;
|
||||
}
|
||||
|
||||
|
||||
export const PlayroomStore = defineStore("PlayroomStore",
|
||||
() =>{
|
||||
const currentPlayroom = ref<PlayroomState>();
|
||||
const members = ref<member[]>([]);
|
||||
const currentUrl = ref<string>("");
|
||||
|
||||
const setCurrentPlayroom = (playroom: PlayroomState) => {
|
||||
currentPlayroom.value = playroom;
|
||||
}
|
||||
|
||||
const getCurrentPlayroom = () =>{
|
||||
return currentPlayroom.value;
|
||||
}
|
||||
|
||||
const getCurrentId = () =>{
|
||||
return currentPlayroom.value?.r_id;
|
||||
}
|
||||
|
||||
const setCurrentUrl = (url: string) => {
|
||||
currentUrl.value = url;
|
||||
}
|
||||
|
||||
const clearPlayroom = () => {
|
||||
currentPlayroom.value = null;
|
||||
currentUrl.value = "";
|
||||
members.value = [];
|
||||
}
|
||||
|
||||
const addmember = (member: member) => {
|
||||
members.value.push(member);
|
||||
}
|
||||
|
||||
const getmembers = (page: number, pageSize: number) => {
|
||||
return members.value.slice((page - 1) * pageSize, page * pageSize);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
currentPlayroom,
|
||||
currentUrl,
|
||||
setCurrentPlayroom,
|
||||
clearPlayroom,
|
||||
addmember,
|
||||
getmembers,
|
||||
}
|
||||
})
|
||||
|
||||
export const videoSocketStore = defineStore("videoSocketStore",{
|
||||
state: () => ({
|
||||
isConnected: false,
|
||||
hasGotMessage: false,
|
||||
id: 0
|
||||
}),
|
||||
|
||||
actions: {
|
||||
connect(id: number) {
|
||||
this.id = id;
|
||||
if (this.isConnected === true) return
|
||||
connectWebSocket(id);
|
||||
this.isConnected = true;
|
||||
},
|
||||
disconnect() {
|
||||
setIsManualClose(true);
|
||||
disconnectWebSocket();
|
||||
this.isConnected = false;
|
||||
},
|
||||
send(message: string) {
|
||||
sendMessage(JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,119 +1,119 @@
|
||||
<template>
|
||||
|
||||
<div class="container">
|
||||
<el-button @Click="createWindow = true">创建房间</el-button>
|
||||
|
||||
<el-table :data="rooms">
|
||||
<el-table-column label="" prop="r_avatar" width="100">
|
||||
<template #default="scope">
|
||||
<!-- 使用 el-avatar 组件显示头像 -->
|
||||
<el-avatar :src="rooms[scope.$index].r_avatar" size="large" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="房间名" prop="r_name"></el-table-column>
|
||||
<el-table-column label="房间ID" prop="r_id"></el-table-column>
|
||||
<el-table-column label="角色" prop="role"></el-table-column>
|
||||
<el-table-column label="简介" prop="r_introduction"></el-table-column>
|
||||
<el-table-column label="">
|
||||
<template #default="scope">
|
||||
<el-button @click="goToRoom(scope.row)">进入房间</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
|
||||
<el-dialog v-model="createWindow" title="创建房间" style="width: 400px;height: 300px;">
|
||||
<el-form ref="form" :model="formData" label-width="80px" @submit.prevent="createroom">
|
||||
<el-form-item label="房间名" prop="roomName">
|
||||
<el-input v-model="formData.roomName" placeholder="请输入房间名" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-button type="primary" native-type="submit">创建</el-button>
|
||||
</el-form>
|
||||
|
||||
</el-dialog>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { PlayroomStore } from '@/store/playroom';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { getPlayrooms, createPlayroom } from '@/api/playroom';
|
||||
|
||||
const roominfo = PlayroomStore()
|
||||
const createWindow = ref(false)
|
||||
const formData = reactive({
|
||||
roomName: ''
|
||||
})
|
||||
|
||||
const rooms = ref([])
|
||||
|
||||
const goToRoom = (r) => {
|
||||
roominfo.setCurrentPlayroom(r);
|
||||
// 跳转到房间页面
|
||||
const baseUrl = window.location.origin;
|
||||
const targetUrl = `${baseUrl}/room`; // 替换为你的目标路由
|
||||
window.open(targetUrl, "room");
|
||||
};
|
||||
|
||||
const createroom = async () => {
|
||||
if (!formData.roomName || formData.roomName.trim() === '') {
|
||||
ElMessage.error('房间名不能为空')
|
||||
return
|
||||
}
|
||||
try {
|
||||
if(await createPlayroom(formData.roomName)){
|
||||
ElMessage.success('创建成功')
|
||||
}else{
|
||||
ElMessage.error('创建失败')
|
||||
}
|
||||
formData.roomName = ''
|
||||
createWindow.value = false
|
||||
rooms.value = await getPlayrooms()
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getrooms = async () => {
|
||||
try {
|
||||
rooms.value = await getPlayrooms()
|
||||
}
|
||||
catch (error) {
|
||||
ElMessage.error('获取房间列表失败' + error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getrooms()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
margin-top: 20px;
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.profile {
|
||||
top: 50px;
|
||||
left: 100px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.profile img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
}
|
||||
<template>
|
||||
|
||||
<div class="container">
|
||||
<el-button @Click="createWindow = true">创建房间</el-button>
|
||||
|
||||
<el-table :data="rooms">
|
||||
<el-table-column label="" prop="r_avatar" width="100">
|
||||
<template #default="scope">
|
||||
<!-- 使用 el-avatar 组件显示头像 -->
|
||||
<el-avatar :src="rooms[scope.$index].r_avatar" size="large" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="房间名" prop="r_name"></el-table-column>
|
||||
<el-table-column label="房间ID" prop="r_id"></el-table-column>
|
||||
<el-table-column label="角色" prop="role"></el-table-column>
|
||||
<el-table-column label="简介" prop="r_introduction"></el-table-column>
|
||||
<el-table-column label="">
|
||||
<template #default="scope">
|
||||
<el-button @click="goToRoom(scope.row)">进入房间</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
|
||||
<el-dialog v-model="createWindow" title="创建房间" style="width: 400px;height: 300px;">
|
||||
<el-form ref="form" :model="formData" label-width="80px" @submit.prevent="createroom">
|
||||
<el-form-item label="房间名" prop="roomName">
|
||||
<el-input v-model="formData.roomName" placeholder="请输入房间名" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-button type="primary" native-type="submit">创建</el-button>
|
||||
</el-form>
|
||||
|
||||
</el-dialog>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { PlayroomStore } from '@/store/playroom';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { getPlayrooms, createPlayroom } from '@/api/playroom';
|
||||
|
||||
const roominfo = PlayroomStore()
|
||||
const createWindow = ref(false)
|
||||
const formData = reactive({
|
||||
roomName: ''
|
||||
})
|
||||
|
||||
const rooms = ref([])
|
||||
|
||||
const goToRoom = (r) => {
|
||||
roominfo.setCurrentPlayroom(r);
|
||||
// 跳转到房间页面
|
||||
const baseUrl = window.location.origin;
|
||||
const targetUrl = `${baseUrl}/room?r_id=${r.r_id}`; // 替换为你的目标路由
|
||||
window.open(targetUrl, "room");
|
||||
};
|
||||
|
||||
const createroom = async () => {
|
||||
if (!formData.roomName || formData.roomName.trim() === '') {
|
||||
ElMessage.error('房间名不能为空')
|
||||
return
|
||||
}
|
||||
try {
|
||||
if(await createPlayroom(formData.roomName)){
|
||||
ElMessage.success('创建成功')
|
||||
}else{
|
||||
ElMessage.error('创建失败')
|
||||
}
|
||||
formData.roomName = ''
|
||||
createWindow.value = false
|
||||
rooms.value = await getPlayrooms()
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getrooms = async () => {
|
||||
try {
|
||||
rooms.value = await getPlayrooms()
|
||||
}
|
||||
catch (error) {
|
||||
ElMessage.error('获取房间列表失败' + error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getrooms()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
margin-top: 20px;
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.profile {
|
||||
top: 50px;
|
||||
left: 100px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.profile img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,149 +1,162 @@
|
||||
import { ref } from "vue";
|
||||
import { userInfoStore } from "@/store/user";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { PlayroomStore } from "@/store/playroom";
|
||||
|
||||
// userinfo 实例
|
||||
const userinfo = userInfoStore();
|
||||
|
||||
// 延迟获取 playroom 实例,避免循环依赖
|
||||
const getPlayroom = () => {
|
||||
return PlayroomStore();
|
||||
};
|
||||
|
||||
|
||||
// WebSocket 实例
|
||||
const socket = ref(null);
|
||||
|
||||
const isManualClose = ref(false);
|
||||
|
||||
const reconnectScheduled = ref(false);
|
||||
|
||||
const retryCount = ref(0);
|
||||
|
||||
export const getRetryCount = () => {
|
||||
return retryCount.value;
|
||||
};
|
||||
|
||||
export const addRetryCount = () => {
|
||||
retryCount.value = retryCount.value + 1;
|
||||
};
|
||||
|
||||
export const resetRetryCount = () => {
|
||||
retryCount.value = 0;
|
||||
};
|
||||
export const setReconnectScheduled = (value) => {
|
||||
reconnectScheduled.value = value;
|
||||
};
|
||||
|
||||
export const getReconnectScheduled = () => {
|
||||
return reconnectScheduled.value;
|
||||
};
|
||||
|
||||
export const setIsManualClose = (value) => {
|
||||
isManualClose.value = value;
|
||||
};
|
||||
|
||||
export const getIsManualClose = () => {
|
||||
return isManualClose.value;
|
||||
};
|
||||
|
||||
// 连接WebSocket
|
||||
export const connectWebSocket = () => {
|
||||
const playroom = getPlayroom();
|
||||
const protocol = window.location.protocol === "https:" ? "wss://" : "ws://";
|
||||
const host = window.location.host;
|
||||
const socketUrl = `${protocol}${host}/ws/video?r_id=${playroom.getCurrentId()}`;
|
||||
|
||||
// const socketUrl = `ws://localhost:8080/online?u_id=${userinfo.user.u_id}&u_name=${userinfo.user.u_name}`;
|
||||
if (socket.value && socket.value.readyState !== WebSocket.CLOSED) {
|
||||
console.log("还在重连中...");
|
||||
return;
|
||||
}
|
||||
const retrytime = getRetryCount();
|
||||
if (retrytime >= 10) {
|
||||
console.log("重连失败,请稍后再试");
|
||||
return;
|
||||
}
|
||||
console.log(retrytime);
|
||||
socket.value = new WebSocket(socketUrl, "token-"+ userinfo.token);
|
||||
|
||||
socket.value.onopen = (event) => {
|
||||
console.log("WebSocket for video 连接已建立", event);
|
||||
setReconnectScheduled(false);
|
||||
setIsManualClose(false);
|
||||
resetRetryCount();
|
||||
};
|
||||
|
||||
//处理消息逻辑
|
||||
socket.value.onmessage = (event) => {
|
||||
console.log("从服务器收到消息:", event.data);
|
||||
try{
|
||||
const MessageData = JSON.parse(event.data);
|
||||
const cmd = MessageData.cmd;
|
||||
switch(cmd){
|
||||
case "VIDEO_SYNC":
|
||||
console.log("视频同步消息", MessageData);
|
||||
break;
|
||||
}
|
||||
}catch(error){
|
||||
console.error("解析 JSON 失败:", error);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
socket.value.onerror = (error) => {
|
||||
console.error("WebSocket for video 发生错误:", error);
|
||||
// console.log(error);
|
||||
setReconnectScheduled(true);
|
||||
socket.value.close();
|
||||
};
|
||||
|
||||
socket.value.onclose = (event) => {
|
||||
if (!getIsManualClose()) {
|
||||
if (getReconnectScheduled()) {
|
||||
socket.value = null;
|
||||
addRetryCount();
|
||||
setTimeout(reConnectWebSocket, 5000);
|
||||
setReconnectScheduled(false);
|
||||
} else {
|
||||
// console.log("websocket因为浏览器省电设置断开");
|
||||
console.log("WebSocket for video 连接已关闭", event);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 断开WebSocket连接
|
||||
export const disconnectWebSocket = () => {
|
||||
if (socket.value && socket.value.readyState === WebSocket.OPEN) {
|
||||
socket.value.close();
|
||||
}
|
||||
};
|
||||
|
||||
// 重连机制
|
||||
export const reConnectWebSocket = () => {
|
||||
connectWebSocket();
|
||||
};
|
||||
|
||||
// 发送消息
|
||||
export const sendMessage = (message) => {
|
||||
if (socket.value && socket.value.readyState === WebSocket.OPEN) {
|
||||
socket.value.send(message);
|
||||
} else {
|
||||
console.warn("WebSocket for video 未连接,无法发送消息");
|
||||
}
|
||||
};
|
||||
|
||||
//没有错误的重连,只是浏览器在后台断开了连接
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (document.hidden) {
|
||||
} else {
|
||||
if (!getIsManualClose() && socket.value.readyState === WebSocket.CLOSED) {
|
||||
if (getReconnectScheduled()) {
|
||||
return;
|
||||
}
|
||||
reConnectWebSocket();
|
||||
}
|
||||
}
|
||||
});
|
||||
import { ref } from "vue";
|
||||
import { userInfoStore } from "@/store/user";
|
||||
|
||||
|
||||
// userinfo 实例
|
||||
const userinfo = userInfoStore();
|
||||
|
||||
const roomid = ref<number>(0);
|
||||
|
||||
|
||||
// WebSocket 实例
|
||||
const socket = ref<WebSocket | null>(null);
|
||||
|
||||
const isManualClose = ref<boolean>(false);
|
||||
|
||||
const reconnectScheduled = ref<boolean>(false);
|
||||
|
||||
const retryCount = ref<number>(0);
|
||||
|
||||
const getRetryCount = () => {
|
||||
return retryCount.value;
|
||||
};
|
||||
|
||||
const addRetryCount = () => {
|
||||
retryCount.value = retryCount.value + 1;
|
||||
};
|
||||
|
||||
const resetRetryCount = () => {
|
||||
retryCount.value = 0;
|
||||
};
|
||||
const setReconnectScheduled = (value: boolean) => {
|
||||
reconnectScheduled.value = value;
|
||||
};
|
||||
|
||||
const getReconnectScheduled = () => {
|
||||
return reconnectScheduled.value;
|
||||
};
|
||||
|
||||
export const setIsManualClose = (value: boolean) => {
|
||||
isManualClose.value = value;
|
||||
};
|
||||
|
||||
const getIsManualClose = () => {
|
||||
return isManualClose.value;
|
||||
};
|
||||
|
||||
// 连接WebSocket
|
||||
export const connectWebSocket = (r_id: number) => {
|
||||
roomid.value = r_id;
|
||||
const protocol = window.location.protocol === "https:" ? "wss://" : "ws://";
|
||||
const host = window.location.host;
|
||||
const socketUrl = `${protocol}${host}/ws/playroom?r_id=${r_id}`;
|
||||
|
||||
// const socketUrl = `ws://localhost:8080/online?u_id=${userinfo.user.u_id}&u_name=${userinfo.user.u_name}`;
|
||||
if (socket.value && socket.value.readyState !== WebSocket.CLOSED) {
|
||||
console.log("还在重连中...");
|
||||
return;
|
||||
}
|
||||
const retrytime = getRetryCount();
|
||||
if (retrytime >= 10) {
|
||||
console.log("重连失败,请稍后再试");
|
||||
return;
|
||||
}
|
||||
console.log(retrytime);
|
||||
socket.value = new WebSocket(socketUrl, "token-"+ userinfo.token);
|
||||
|
||||
socket.value.onopen = (event: any) => {
|
||||
console.log("WebSocket for video 连接已建立", event);
|
||||
setReconnectScheduled(false);
|
||||
setIsManualClose(false);
|
||||
resetRetryCount();
|
||||
};
|
||||
|
||||
//处理消息逻辑
|
||||
socket.value.onmessage = (event) => {
|
||||
console.log("从服务器收到消息:", event.data);
|
||||
try{
|
||||
const MessageData = JSON.parse(event.data);
|
||||
const cmd = MessageData.cmd;
|
||||
switch(cmd){
|
||||
case "PING":
|
||||
console.log("收到PING消息");
|
||||
const msg = {
|
||||
cmd: "PONG",
|
||||
from: MessageData.to,
|
||||
// 可扩展字段
|
||||
time: new Date().toLocaleString()
|
||||
}
|
||||
sendMessage(msg);
|
||||
break;
|
||||
case "VIDEO_SYNC":
|
||||
// console.log("视频同步消息", MessageData);
|
||||
break;
|
||||
}
|
||||
}catch(error){
|
||||
console.error("解析 JSON 失败:", error);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
socket.value.onerror = (error) => {
|
||||
console.error("WebSocket for video 发生错误:", error);
|
||||
// console.log(error);
|
||||
setReconnectScheduled(true);
|
||||
socket.value.close();
|
||||
};
|
||||
|
||||
socket.value.onclose = (event) => {
|
||||
if (!getIsManualClose()) {
|
||||
if (getReconnectScheduled()) {
|
||||
socket.value = null;
|
||||
addRetryCount();
|
||||
setTimeout(reConnectWebSocket, 5000);
|
||||
setReconnectScheduled(false);
|
||||
} else {
|
||||
// console.log("websocket因为浏览器省电设置断开");
|
||||
console.log("WebSocket for video 连接已关闭", event);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 断开WebSocket连接
|
||||
export const disconnectWebSocket = () => {
|
||||
if (socket.value && socket.value.readyState === WebSocket.OPEN) {
|
||||
roomid.value = 0;
|
||||
socket.value.close();
|
||||
}
|
||||
};
|
||||
|
||||
// 重连机制
|
||||
export const reConnectWebSocket = () => {
|
||||
connectWebSocket(roomid.value);
|
||||
};
|
||||
|
||||
// 发送消息
|
||||
export const sendMessage = (message: any) => {
|
||||
try{
|
||||
const jsonmessage = JSON.stringify(message);
|
||||
if (socket.value && socket.value.readyState === WebSocket.OPEN) {
|
||||
socket.value.send(jsonmessage);
|
||||
} else {
|
||||
console.warn("WebSocket for video 未连接,无法发送消息");
|
||||
}
|
||||
}
|
||||
catch(error){
|
||||
console.error("Failed to stringify message:", error);
|
||||
}
|
||||
};
|
||||
|
||||
//没有错误的重连,只是浏览器在后台断开了连接
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (document.hidden) {
|
||||
} else {
|
||||
if (!getIsManualClose() && socket.value.readyState === WebSocket.CLOSED) {
|
||||
if (getReconnectScheduled()) {
|
||||
return;
|
||||
}
|
||||
reConnectWebSocket();
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user