设置了默认地址并修复退出房间异常问题,已部署成功
This commit is contained in:
parent
b7f087536b
commit
985ff72906
3
.gitignore
vendored
3
.gitignore
vendored
@ -36,9 +36,6 @@ src-tauri/target/
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Config
|
||||
config.json
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
@ -75,6 +75,26 @@ io.on('connection', (socket) => {
|
||||
socket.emit('room-users', roomUsers);
|
||||
});
|
||||
|
||||
socket.on('leave-room', ({ roomId, userId, socketId }) => {
|
||||
const user = users.get(socketId);
|
||||
if (user && user.roomId === roomId) {
|
||||
const room = rooms.get(roomId);
|
||||
if (room) {
|
||||
room.delete(socketId);
|
||||
socket.to(roomId).emit('user-left', {
|
||||
userId: user.userId,
|
||||
socketId: socketId
|
||||
});
|
||||
|
||||
if (room.size === 0) {
|
||||
rooms.delete(roomId);
|
||||
}
|
||||
}
|
||||
users.delete(socketId);
|
||||
socket.leave(roomId);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('signal', ({ targetSocketId, signal }) => {
|
||||
const targetUser = users.get(targetSocketId);
|
||||
if (targetUser) {
|
||||
|
||||
35
src/App.vue
35
src/App.vue
@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { io } from 'socket.io-client';
|
||||
|
||||
// 导入组件
|
||||
@ -16,7 +16,7 @@ import { useWebRTC } from './composables/useWebRTC.js';
|
||||
import { useFileTransfer } from './composables/useFileTransfer.js';
|
||||
|
||||
// 使用组合式函数
|
||||
const { socket, userId, nickname, connected, roomUsers, roomId, joinRoom, serverUrl, connectToServer, disconnectFromServer } = useSocket();
|
||||
const { socket, userId, nickname, connected, roomUsers, roomId, joinRoom, leaveRoom, onUserLeft, serverUrl, connectToServer, disconnectFromServer } = useSocket();
|
||||
const localServerUrl = ref(serverUrl.value);
|
||||
|
||||
// 处理连接按钮点击
|
||||
@ -35,7 +35,8 @@ const {
|
||||
createPeerConnection,
|
||||
handleSignal,
|
||||
setupDataChannel,
|
||||
closePeerConnection
|
||||
closePeerConnection,
|
||||
closeAllPeerConnections
|
||||
} = useWebRTC();
|
||||
const {
|
||||
transfers,
|
||||
@ -45,7 +46,8 @@ const {
|
||||
sendFile,
|
||||
acceptFile,
|
||||
rejectFile,
|
||||
selectFile
|
||||
selectFile,
|
||||
clearTransfers
|
||||
} = useFileTransfer();
|
||||
|
||||
// 连接用户
|
||||
@ -100,8 +102,29 @@ function handleDisconnectUser(socketId) {
|
||||
closePeerConnection(socketId);
|
||||
}
|
||||
|
||||
// 监听信号
|
||||
// 判断是否有文件正在传输
|
||||
const hasActiveTransfer = computed(() => {
|
||||
return transfers.value.some(t =>
|
||||
t.status === 'sending' || t.status === 'receiving'
|
||||
);
|
||||
});
|
||||
|
||||
// 处理退出房间事件
|
||||
function handleLeaveRoom() {
|
||||
if (hasActiveTransfer.value) {
|
||||
return;
|
||||
}
|
||||
closeAllPeerConnections();
|
||||
clearTransfers();
|
||||
leaveRoom();
|
||||
}
|
||||
|
||||
// 设置用户离开回调和监听信号
|
||||
onMounted(() => {
|
||||
onUserLeft.value = (socketId) => {
|
||||
closePeerConnection(socketId);
|
||||
};
|
||||
|
||||
if (socket.value) {
|
||||
socket.value.on('signal', async ({ senderSocketId, signal }) => {
|
||||
await handleSignal(
|
||||
@ -182,8 +205,10 @@ onUnmounted(() => {
|
||||
:peer-connections="peerConnections"
|
||||
:room-id="roomId"
|
||||
:current-socket-id="socket?.id"
|
||||
:has-active-transfer="hasActiveTransfer"
|
||||
@connect-user="connectToUser"
|
||||
@disconnect-user="handleDisconnectUser"
|
||||
@leave-room="handleLeaveRoom"
|
||||
/>
|
||||
|
||||
<FileSend
|
||||
|
||||
@ -1,6 +1,16 @@
|
||||
<template>
|
||||
<div class="section" v-if="roomId">
|
||||
<h2>{{ $t('room.users_in_room') }}</h2>
|
||||
<div class="room-header">
|
||||
<h2>{{ $t('room.users_in_room') }}</h2>
|
||||
<button
|
||||
@click="leaveRoom"
|
||||
:disabled="hasActiveTransfer"
|
||||
class="leave-room-btn"
|
||||
:title="hasActiveTransfer ? $t('room.cannot_leave_room') : ''"
|
||||
>
|
||||
{{ $t('room.leave_room') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="room-info">
|
||||
<span class="room-id">{{ $t('room.room_id') }}: {{ roomId }}</span>
|
||||
<span class="user-count">{{ $t('room.users_in_room') }}: {{ roomUsers.length }}</span>
|
||||
@ -57,11 +67,15 @@ const props = defineProps({
|
||||
currentSocketId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
hasActiveTransfer: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
// 定义组件emit事件
|
||||
const emit = defineEmits(['connectUser', 'disconnectUser']);
|
||||
const emit = defineEmits(['connectUser', 'disconnectUser', 'leaveRoom']);
|
||||
|
||||
// 判断是否为当前用户
|
||||
function isCurrentUser(socketId) {
|
||||
@ -77,6 +91,11 @@ function connectToUser(socketId) {
|
||||
function disconnectFromUser(socketId) {
|
||||
emit('disconnectUser', socketId);
|
||||
}
|
||||
|
||||
// 处理退出房间事件
|
||||
function leaveRoom() {
|
||||
emit('leaveRoom');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -88,6 +107,42 @@ function disconnectFromUser(socketId) {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.room-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.room-header h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.leave-room-btn {
|
||||
padding: 8px 16px;
|
||||
background: #ff9800;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.leave-room-btn:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.leave-room-btn:hover:not(:disabled) {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.leave-room-btn:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.room-info {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
|
||||
@ -319,6 +319,11 @@ export function useFileTransfer() {
|
||||
}
|
||||
}
|
||||
|
||||
function clearTransfers() {
|
||||
transfers.value = [];
|
||||
pendingTransfers.value = [];
|
||||
}
|
||||
|
||||
return {
|
||||
transfers,
|
||||
pendingTransfers,
|
||||
@ -327,6 +332,7 @@ export function useFileTransfer() {
|
||||
sendFile,
|
||||
acceptFile,
|
||||
rejectFile,
|
||||
selectFile
|
||||
selectFile,
|
||||
clearTransfers
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,16 +1,12 @@
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { io } from 'socket.io-client';
|
||||
import { generateUserId } from '../utils';
|
||||
import config from '../../config.json';
|
||||
|
||||
|
||||
function isTauri() {
|
||||
return window.__TAURI__ !== undefined;
|
||||
}
|
||||
|
||||
function getDefaultServerUrl() {
|
||||
return config.defaultServerUrl || 'http://localhost:3000';
|
||||
}
|
||||
|
||||
export function useSocket() {
|
||||
const socket = ref(null);
|
||||
const userId = ref('');
|
||||
@ -18,7 +14,8 @@ export function useSocket() {
|
||||
const connected = ref(false);
|
||||
const roomUsers = ref([]);
|
||||
const roomId = ref('');
|
||||
const serverUrl = ref(localStorage.getItem('p2p-server-url') || getDefaultServerUrl());
|
||||
const serverUrl = ref(localStorage.getItem('p2p-server-url') || 'wss://p2p-file-transfer.cloyir.com');
|
||||
const onUserLeft = ref(null);
|
||||
|
||||
onMounted(() => {
|
||||
userId.value = generateUserId();
|
||||
@ -36,10 +33,10 @@ export function useSocket() {
|
||||
if (socket.value) {
|
||||
socket.value.disconnect();
|
||||
}
|
||||
|
||||
|
||||
serverUrl.value = url;
|
||||
localStorage.setItem('p2p-server-url', url);
|
||||
|
||||
|
||||
const socketOptions = {
|
||||
transports: ['websocket', 'polling'],
|
||||
reconnection: true,
|
||||
@ -58,7 +55,7 @@ export function useSocket() {
|
||||
} else {
|
||||
socketOptions.withCredentials = false;
|
||||
}
|
||||
|
||||
|
||||
socket.value = io(url, socketOptions);
|
||||
|
||||
socket.value.on('connect', () => {
|
||||
@ -83,6 +80,9 @@ export function useSocket() {
|
||||
|
||||
socket.value.on('user-left', ({ userId: leftUserId, socketId }) => {
|
||||
roomUsers.value = roomUsers.value.filter(u => u.socketId !== socketId);
|
||||
if (onUserLeft.value) {
|
||||
onUserLeft.value(socketId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -99,14 +99,26 @@ export function useSocket() {
|
||||
nickname.value = newNickname;
|
||||
localStorage.setItem('p2p-nickname', newNickname);
|
||||
}
|
||||
socket.value.emit('join-room', {
|
||||
roomId: roomId.value,
|
||||
socket.value.emit('join-room', {
|
||||
roomId: roomId.value,
|
||||
userId: userId.value,
|
||||
nickname: nickname.value
|
||||
nickname: nickname.value
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function leaveRoom() {
|
||||
if (roomId.value && socket.value) {
|
||||
socket.value.emit('leave-room', {
|
||||
roomId: roomId.value,
|
||||
userId: userId.value,
|
||||
socketId: socket.value.id
|
||||
});
|
||||
roomId.value = '';
|
||||
roomUsers.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
socket,
|
||||
userId,
|
||||
@ -115,8 +127,10 @@ export function useSocket() {
|
||||
roomUsers,
|
||||
roomId,
|
||||
serverUrl,
|
||||
joinRoom,
|
||||
onUserLeft,
|
||||
connectToServer,
|
||||
disconnectFromServer
|
||||
disconnectFromServer,
|
||||
joinRoom,
|
||||
leaveRoom
|
||||
};
|
||||
}
|
||||
|
||||
@ -137,6 +137,8 @@ export function useWebRTC() {
|
||||
channel.onclose = () => {
|
||||
console.log('Data channel closed with:', socketId);
|
||||
dataChannelReady.value.delete(socketId);
|
||||
dataChannels.value.delete(socketId);
|
||||
peerConnections.value.delete(socketId);
|
||||
};
|
||||
}
|
||||
|
||||
@ -153,6 +155,20 @@ export function useWebRTC() {
|
||||
}
|
||||
}
|
||||
|
||||
function closeAllPeerConnections() {
|
||||
peerConnections.value.forEach((pc, socketId) => {
|
||||
pc.close();
|
||||
});
|
||||
peerConnections.value.clear();
|
||||
|
||||
dataChannels.value.forEach((dc) => {
|
||||
dc.close();
|
||||
});
|
||||
dataChannels.value.clear();
|
||||
|
||||
dataChannelReady.value.clear();
|
||||
}
|
||||
|
||||
return {
|
||||
peerConnections,
|
||||
dataChannels,
|
||||
@ -160,6 +176,7 @@ export function useWebRTC() {
|
||||
createPeerConnection,
|
||||
handleSignal,
|
||||
setupDataChannel,
|
||||
closePeerConnection
|
||||
closePeerConnection,
|
||||
closeAllPeerConnections
|
||||
};
|
||||
}
|
||||
|
||||
@ -17,7 +17,9 @@ export default {
|
||||
nickname: 'Nickname',
|
||||
join: 'Join',
|
||||
leave: 'Leave',
|
||||
users_in_room: 'Users in Room'
|
||||
users_in_room: 'Users in Room',
|
||||
leave_room: 'Leave Room',
|
||||
cannot_leave_room: 'Cannot leave room while transferring files'
|
||||
},
|
||||
file_transfer: {
|
||||
connect: 'Connect',
|
||||
|
||||
@ -17,7 +17,9 @@ export default {
|
||||
nickname: '昵称',
|
||||
join: '加入',
|
||||
leave: '离开',
|
||||
users_in_room: '房间内用户'
|
||||
users_in_room: '房间内用户',
|
||||
leave_room: '退出房间',
|
||||
cannot_leave_room: '正在传输文件,无法退出房间'
|
||||
},
|
||||
file_transfer: {
|
||||
connect: '连接',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user