-export const port = Number(process.env.JUNCTION_SERVER_PORT || 8000)
+export const port = Number(process.env.JUNCTION_SERVER_PORT || 8000);
-export function addPeer(peerId, shouldCreateOffer) {
- return {
+const internals = {
+ emitter(name, data, socket) {
+ socket.emit(name, data);
+ console.debug(`[${name}] ${JSON.stringify(data)}`);
+ },
+};
+
+export const types = {
+ /* Listened */
+ CONNECTION: "connection",
+ JOIN: "join",
+ DISCONNECTING: "disconnecting",
+ RELAY_ICE_CANDIDATE: "relayICECandidate",
+ RELAY_OFFER: "relayOffer",
+ RELAY_ANSWER: "relayAnswer",
+
+ /* Emitted */
+ ADD_PEER: "addPeer",
+ REMOVE_PEER: "removePeer",
+ OFFER_RECEIVED: "offerReceived",
+ ANSWER_RECEIVED: "answerReceived",
+ ICE_CANDIDATE_RECEIVED: "ICECandidateReceived",
+};
+
+export function addPeer(peerId) {
+ return internals.emitter.bind(null, types.ADD_PEER, {
peerId,
- shouldCreateOffer,
- }
+ });
}
export function removePeer(peerId) {
- return {
- peerId,
- }
-}
-
-export function SessionDescriptionReceived(peerId, sessionDescription) {
- return {
- peerId,
- sessionDescription,
- }
+ return internals.emitter.bind(null, types.REMOVE_PEER, {
+ peerId,
+ });
}
export function ICECandidateReceived(peerId, candidate) {
- return {
- peerId,
- candidate
- }
+ return internals.emitter.bind(null, types.ICE_CANDIDATE_RECEIVED, {
+ peerId,
+ candidate,
+ });
}
export function offerReceived(peerId, offer) {
- return {
- peerId,
- offer
- }
+ return internals.emitter.bind(null, types.OFFER_RECEIVED, {
+ peerId,
+ offer,
+ });
}
export function answerReceived(peerId, answer) {
- return {
- peerId,
- answer
- }
+ return internals.emitter.bind(null, types.ANSWER_RECEIVED, {
+ peerId,
+ answer,
+ });
}
-
-export const types = {
- ADD_PEER: 'addPeer',
- REMOVE_PEER: 'removePeer',
- RELAY_SESSION_DESCRIPTION: 'relaySessionDescription',
- RELAY_ICE_CANDIDATE: 'relayICECandidate',
- OFFER_RECEIVED: 'offerReceived',
- ANSWER_RECEIVED: 'answerReceived',
- ICE_CANDIDATE_RECEIVED: 'ICECandidateReceived',
- SESSION_DESCRIPTION_RECEIVED: 'SessionDescriptionReceived',
-};
-import { Server } from 'socket.io';
-import { port } from './config.js';
-import * as events from './events.js';
+import { Server } from "socket.io";
+import { port } from "./config.js";
+import * as events from "./events.js";
const server = new Server(port);
-console.log(`Listening on port ${port}`);
+console.debug(`Listening on port ${port}`);
const rooms = {};
-server.on('connection', (socket) => {
- const me = socket.id;
+server.on(events.types.CONNECTION, (socket) => {
+ const me = socket.id;
- console.log(`[CONNECT] New client connected with ID ${me}`);
+ console.debug(`[CONNECT] New client connected with ID ${me}`);
- socket.on('join', async (data) => {
- const room = data.room;
- socket.join(room);
+ socket.on(events.types.JOIN, async ({ room }) => {
+ socket.join(room);
- if (!rooms[room]) {
- rooms[room] = [];
- }
+ if (!rooms[room]) {
+ rooms[room] = [];
+ }
- rooms[room].push(socket.id);
+ rooms[room].push(socket.id);
- const sockets = await server.in(room).fetchSockets()
- sockets.forEach((peer) => {
- if (peer.id !== me) {
- peer.emit(events.types.ADD_PEER, events.addPeer(me, false));
- socket.emit(events.types.ADD_PEER, events.addPeer(peer.id, true));
- }
- });
- console.log(`[CONNECT] Client ${me} added to room ${room}`);
+ const sockets = await server.in(room).fetchSockets();
+ sockets.forEach((peer) => {
+ if (peer.id !== me) {
+ events.addPeer(me)(peer);
+ events.addPeer(peer.id)(socket);
+ }
});
-
- socket.on('disconnecting', () => {
-
- for (const room in rooms) {
- if (rooms[room].includes(me)) {
- rooms[room] = rooms[room].filter(id => id !== me);
- socket.to(room).emit(events.types.REMOVE_PEER, events.removePeer(me));
- if (rooms[room].length === 0) {
- delete rooms[room];
- }
+ });
+
+ socket.on(events.types.DISCONNECTING, () => {
+ for (const room in rooms) {
+ if (rooms[room].includes(me)) {
+ rooms[room] = rooms[room].filter((id) => id !== me);
+ events.removePeer(me)(socket.to(room));
+ if (rooms[room].length === 0) {
+ delete rooms[room];
}
}
- console.log(`[DISCONNECT] Client ${me} has disconnected and has been removed from all rooms`);
- });
+ }
+ });
- socket.on('relayICECandidate', async (data) => {
+ socket.on(events.types.RELAY_ICE_CANDIDATE, async ({ candidate, peerId }) => {
+ events.ICECandidateReceived(me, candidate)(socket.to(peerId));
+ });
- socket.to(data.peerId).emit(events.types.ICE_CANDIDATE_RECEIVED, events.ICECandidateReceived(me, data.candidate))
- console.log(`[RELAY_ICE_CANDIDATE] ICE candidate for client ${me} has been relayed to all peers`);
- });
-
- socket.on('relayOffer', async (data) => {
-
- socket.to(data.peerId).emit(events.types.OFFER_RECEIVED, events.offerReceived(me, data.offer))
- console.log(`[RELAY_OFFER] ICE offer for client ${me} has been relayed to all peers`);
- });
-
- socket.on('relayAnswer', async (data) => {
+ socket.on(events.types.RELAY_OFFER, async ({ offer, peerId }) => {
+ events.offerReceived(me, offer)(socket.to(peerId));
+ });
- socket.to(data.peerId).emit(events.types.ANSWER_RECEIVED, events.answerReceived(me, data.answer))
- console.log(`[RELAY_OFFER] ICE offer for client ${me} has been relayed to all peers`);
- });
+ socket.on(events.types.RELAY_ANSWER, async ({ answer, peerId }) => {
+ events.answerReceived(me, answer)(socket.to(peerId));
+ });
});
-lockfileVersion: '6.0'
+lockfileVersion: "6.0"
settings:
autoInstallPeers: true
version: 4.7.2
packages:
-
/@socket.io/component-emitter@3.1.0:
- resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==}
+ resolution:
+ {
+ integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==,
+ }
dev: false
/@types/cookie@0.4.1:
- resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==}
+ resolution:
+ {
+ integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==,
+ }
dev: false
/@types/cors@2.8.13:
- resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==}
+ resolution:
+ {
+ integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==,
+ }
dependencies:
- '@types/node': 20.5.6
+ "@types/node": 20.5.6
dev: false
/@types/node@20.5.6:
- resolution: {integrity: sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==}
+ resolution:
+ {
+ integrity: sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==,
+ }
dev: false
/accepts@1.3.8:
- resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
- engines: {node: '>= 0.6'}
+ resolution:
+ {
+ integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==,
+ }
+ engines: { node: ">= 0.6" }
dependencies:
mime-types: 2.1.35
negotiator: 0.6.3
dev: false
/base64id@2.0.0:
- resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
- engines: {node: ^4.5.0 || >= 5.9}
+ resolution:
+ {
+ integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==,
+ }
+ engines: { node: ^4.5.0 || >= 5.9 }
dev: false
/cookie@0.4.2:
- resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
- engines: {node: '>= 0.6'}
+ resolution:
+ {
+ integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==,
+ }
+ engines: { node: ">= 0.6" }
dev: false
/cors@2.8.5:
- resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
- engines: {node: '>= 0.10'}
+ resolution:
+ {
+ integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==,
+ }
+ engines: { node: ">= 0.10" }
dependencies:
object-assign: 4.1.1
vary: 1.1.2
dev: false
/debug@4.3.4:
- resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
- engines: {node: '>=6.0'}
+ resolution:
+ {
+ integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==,
+ }
+ engines: { node: ">=6.0" }
peerDependencies:
- supports-color: '*'
+ supports-color: "*"
peerDependenciesMeta:
supports-color:
optional: true
dev: false
/engine.io-parser@5.2.1:
- resolution: {integrity: sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==}
- engines: {node: '>=10.0.0'}
+ resolution:
+ {
+ integrity: sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==,
+ }
+ engines: { node: ">=10.0.0" }
dev: false
/engine.io@6.5.2:
- resolution: {integrity: sha512-IXsMcGpw/xRfjra46sVZVHiSWo/nJ/3g1337q9KNXtS6YRzbW5yIzTCb9DjhrBe7r3GZQR0I4+nq+4ODk5g/cA==}
- engines: {node: '>=10.2.0'}
+ resolution:
+ {
+ integrity: sha512-IXsMcGpw/xRfjra46sVZVHiSWo/nJ/3g1337q9KNXtS6YRzbW5yIzTCb9DjhrBe7r3GZQR0I4+nq+4ODk5g/cA==,
+ }
+ engines: { node: ">=10.2.0" }
dependencies:
- '@types/cookie': 0.4.1
- '@types/cors': 2.8.13
- '@types/node': 20.5.6
+ "@types/cookie": 0.4.1
+ "@types/cors": 2.8.13
+ "@types/node": 20.5.6
accepts: 1.3.8
base64id: 2.0.0
cookie: 0.4.2
dev: false
/mime-db@1.52.0:
- resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
- engines: {node: '>= 0.6'}
+ resolution:
+ {
+ integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==,
+ }
+ engines: { node: ">= 0.6" }
dev: false
/mime-types@2.1.35:
- resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
- engines: {node: '>= 0.6'}
+ resolution:
+ {
+ integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==,
+ }
+ engines: { node: ">= 0.6" }
dependencies:
mime-db: 1.52.0
dev: false
/ms@2.1.2:
- resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+ resolution:
+ {
+ integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==,
+ }
dev: false
/negotiator@0.6.3:
- resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
- engines: {node: '>= 0.6'}
+ resolution:
+ {
+ integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==,
+ }
+ engines: { node: ">= 0.6" }
dev: false
/object-assign@4.1.1:
- resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
- engines: {node: '>=0.10.0'}
+ resolution:
+ {
+ integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==,
+ }
+ engines: { node: ">=0.10.0" }
dev: false
/socket.io-adapter@2.5.2:
- resolution: {integrity: sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==}
+ resolution:
+ {
+ integrity: sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==,
+ }
dependencies:
ws: 8.11.0
transitivePeerDependencies:
dev: false
/socket.io-parser@4.2.4:
- resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==}
- engines: {node: '>=10.0.0'}
+ resolution:
+ {
+ integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==,
+ }
+ engines: { node: ">=10.0.0" }
dependencies:
- '@socket.io/component-emitter': 3.1.0
+ "@socket.io/component-emitter": 3.1.0
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/socket.io@4.7.2:
- resolution: {integrity: sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==}
- engines: {node: '>=10.2.0'}
+ resolution:
+ {
+ integrity: sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==,
+ }
+ engines: { node: ">=10.2.0" }
dependencies:
accepts: 1.3.8
base64id: 2.0.0
dev: false
/vary@1.1.2:
- resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
- engines: {node: '>= 0.8'}
+ resolution:
+ {
+ integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==,
+ }
+ engines: { node: ">= 0.8" }
dev: false
/ws@8.11.0:
- resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==}
- engines: {node: '>=10.0.0'}
+ resolution:
+ {
+ integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==,
+ }
+ engines: { node: ">=10.0.0" }
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ^5.0.2