129 lines
3.1 KiB
JavaScript
129 lines
3.1 KiB
JavaScript
import Koa from 'koa';
|
|
import Router from 'koa-router';
|
|
import bodyParser from 'koa-bodyparser';
|
|
import cors from '@koa/cors';
|
|
import { createServer } from 'http';
|
|
import { Server } from 'socket.io';
|
|
import os from 'os';
|
|
import signalRouter from './routes/signal.js';
|
|
import filesRouter from './routes/files.js';
|
|
|
|
const app = new Koa();
|
|
const router = new Router();
|
|
const httpServer = createServer(app);
|
|
|
|
const io = new Server(httpServer, {
|
|
cors: {
|
|
origin: '*',
|
|
methods: ['GET', 'POST'],
|
|
credentials: true,
|
|
allowedHeaders: ['Content-Type', 'Authorization']
|
|
},
|
|
transports: ['websocket', 'polling']
|
|
});
|
|
|
|
app.use(cors({
|
|
origin: '*',
|
|
credentials: true,
|
|
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
allowHeaders: ['Content-Type', 'Authorization']
|
|
}));
|
|
app.use(bodyParser());
|
|
|
|
app.use(async (ctx, next) => {
|
|
ctx.io = io;
|
|
await next();
|
|
});
|
|
|
|
router.get('/', async (ctx) => {
|
|
ctx.body = {
|
|
message: 'P2P File Transfer Server',
|
|
version: '1.0.0'
|
|
};
|
|
});
|
|
|
|
app.use(router.routes());
|
|
app.use(router.allowedMethods());
|
|
|
|
app.use(signalRouter.routes());
|
|
app.use(signalRouter.allowedMethods());
|
|
|
|
app.use(filesRouter.routes());
|
|
app.use(filesRouter.allowedMethods());
|
|
|
|
const rooms = new Map();
|
|
const users = new Map();
|
|
|
|
io.on('connection', (socket) => {
|
|
console.log('User connected:', socket.id);
|
|
|
|
socket.on('join-room', ({ roomId, userId, nickname }) => {
|
|
socket.join(roomId);
|
|
users.set(socket.id, { roomId, userId, nickname });
|
|
|
|
const room = rooms.get(roomId) || new Set();
|
|
room.add(socket.id);
|
|
rooms.set(roomId, room);
|
|
|
|
socket.to(roomId).emit('user-joined', { userId, socketId: socket.id, nickname });
|
|
|
|
const roomUsers = Array.from(room).map(id => ({
|
|
socketId: id,
|
|
userId: users.get(id)?.userId,
|
|
nickname: users.get(id)?.nickname
|
|
}));
|
|
socket.emit('room-users', roomUsers);
|
|
});
|
|
|
|
socket.on('signal', ({ targetSocketId, signal }) => {
|
|
const targetUser = users.get(targetSocketId);
|
|
if (targetUser) {
|
|
io.to(targetSocketId).emit('signal', {
|
|
senderSocketId: socket.id,
|
|
signal
|
|
});
|
|
}
|
|
});
|
|
|
|
socket.on('disconnect', () => {
|
|
console.log('User disconnected:', socket.id);
|
|
const user = users.get(socket.id);
|
|
if (user) {
|
|
const room = rooms.get(user.roomId);
|
|
if (room) {
|
|
room.delete(socket.id);
|
|
socket.to(user.roomId).emit('user-left', {
|
|
userId: user.userId,
|
|
socketId: socket.id
|
|
});
|
|
|
|
if (room.size === 0) {
|
|
rooms.delete(user.roomId);
|
|
}
|
|
}
|
|
users.delete(socket.id);
|
|
}
|
|
});
|
|
});
|
|
|
|
const PORT = process.env.PORT || 3000;
|
|
const HOST = process.env.HOST || '0.0.0.0';
|
|
|
|
httpServer.listen(PORT, HOST, () => {
|
|
console.log(`P2P Transfer Server running on http://${HOST}:${PORT}`);
|
|
console.log(`Local access: http://localhost:${PORT}`);
|
|
console.log(`LAN access: http://${getLocalIP()}:${PORT}`);
|
|
});
|
|
|
|
function getLocalIP() {
|
|
const interfaces = os.networkInterfaces();
|
|
for (const name of Object.keys(interfaces)) {
|
|
for (const iface of interfaces[name]) {
|
|
if (iface.family === 'IPv4' && !iface.internal) {
|
|
return iface.address;
|
|
}
|
|
}
|
|
}
|
|
return 'localhost';
|
|
}
|