socket-rtc
Version:
SocketRTC is a library that combines WebRTC and WebSocket to facilitate peer-to-peer communication. It allows for real-time communication between browsers and Node.js environments using WebRTC for direct peer-to-peer connections and WebSocket for signalin
189 lines (155 loc) • 5.5 kB
JavaScript
const SimplePeer = require('simple-peer');
const IS_BROWSER = typeof window != 'undefined';
class SocketRTC {
constructor(socketConfig, id = "", rtcconfig = {}) {
this.id = id;
this.socket = null;
this.events = {};
if (IS_BROWSER) {
// Browser environment
this.config = Object.assign({initiator: true}, rtcconfig);
const socketioclient = require('socket.io-client');
this.socket = socketioclient(socketConfig.url, {query: {
customID: this.id
}});
this.initializeClient();
} else {
// Node.js environment
const wrtc = require('wrtc');
this.config = Object.assign({ wrtc: wrtc }, rtcconfig);
this.io = require('socket.io')(socketConfig.server);
this.initializeServer();
}
}
/**
* Adds a listener for the specified event.
*
* @param {string} event - The event to listen for.
* @param {Function} listener - The function to execute when the event is triggered.
*/
on(event, listener) {
// If the event doesn't exist in the events object, create an empty array for it
if (!this.events[event]) {
this.events[event] = [];
}
// Add the listener to the event's array of listeners
this.events[event].push(listener);
}
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(...args));
}
}
initializeServer() {
const clients = {};
this.io.on('connection', (socket) => {
this.socket = socket;
const peer = new SimplePeer(this.config);
const id = socket.handshake.query['customID'];
clients[id] = peer;
// console.log('socket connected', socket.id);
peer.on('connect', () => {
this.emit('connect', {id, pc: peer});
});
peer.on('signal', (data) => {
this.socket.emit('signal', data);
});
peer.on('data', (data) => {
this.emit('message', data);
sendMessage(data);
});
peer.on('close', () => {
console.log('peerconnection closed');
delete clients[id];
});
peer.on('error', (err) => {
this.emit('error', err);
})
socket.on('signal', (data) => {
peer.signal(data);
});
socket.on("disconnect", async (event) => {
this.emit('disconnect', event);
delete clients[id];
peer.destroy();
})
socket.on('error', (err) => {
this.emit('error', err);
});
})
const sendMessage = (data) => {
const pdata = JSON.parse(data);
const allClients = Object.keys(clients);
for (let i = 0; i < allClients.length; i++) {
// if (allClients[i] !== pdata.from) {
// console.log(`Sending message from ${pdata.sender} to ${allClients[i]}`)
try {
clients[allClients[i]].send(data);
} catch (error) {
console.log(`error sending to ${allClients[i]}`, error.message)
}
// }
};
}
this.send = sendMessage;
const except = (id) => {
// const excludedClient = clients[id];
const sendExcept = (message) => {
Object.entries(clients).forEach(([clientId, client]) => {
if (clientId !== id && client.connected) {
client.send(message);
}
});
};
return {
send: sendExcept,
emit
};
}
this.except = except;
}
initializeClient() {
// const clients = {};
this.socket.on('connect', () => {
// console.log('socket connected');
});
const peer = new SimplePeer(this.config);
// console.log(peer)
peer.on('signal', (data) => {
this.socket.emit('signal', data);
});
peer.on('connect', () => {
this.emit('connect');
});
peer.on('data', (data) => {
// const pdata = JSON.parse(data)
this.emit('message', data);
// console.log(`Received message from ${pdata.from}: ${pdata.data}`);
// chatBox.value += 'Peer: ' + data + '\n';
});
peer.on('close', () => {
peer.destroy();
});
peer.on('error', (err) => {
this.emit('error', err);
})
this.socket.on('signal', (data) => {
peer.signal(data);
});
this.socket.on('disconnect', (event) => {
this.emit('disconnect', event);
});
this.socket.on('error', (err) => {
this.emit('error', err);
});
const sendMessage = (message) => {
if (peer && peer.connected) {
peer.send(message);
} else {
console.error('Peer is not connected');
}
}
this.send = sendMessage;
}
}
module.exports = SocketRTC;