| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /* eslint-disable @typescript-eslint/no-var-requires */
- const yargs = require('yargs/yargs');
- const { hideBin } = require('yargs/helpers');
- const nodeDataChannel = require('../../lib/index');
- const WebSocket = require('ws');
- const readline = require('readline');
- // Init Logger
- nodeDataChannel.initLogger('Debug');
- // PeerConnection Map
- const pcMap = {};
- const dcArr = [];
- // Local ID
- const id = randomId(4);
- // Message Size
- const MESSAGE_SIZE = 65535;
- // Buffer Size
- const BUFFER_SIZE = MESSAGE_SIZE * 0;
- // Args
- const argv = yargs(hideBin(process.argv))
- .option('disableSend', {
- type: 'boolean',
- description: 'Disable Send',
- default: false,
- })
- .option('wsUrl', {
- type: 'string',
- description: 'Web Socket URL',
- default: 'ws://localhost:8000',
- })
- .option('dataChannelCount', {
- type: 'number',
- description: 'Data Channel Count To Create',
- default: 1,
- }).argv;
- // Disable Send
- const disableSend = argv.disableSend;
- if (disableSend) console.log('Send Disabled!');
- // Signaling Server
- const wsUrl = process.env.WS_URL || argv.wsUrl;
- console.log(wsUrl);
- const dataChannelCount = argv.dataChannelCount;
- // Read Line Interface
- const rl = readline.createInterface({
- input: process.stdin,
- output: process.stdout,
- });
- const ws = new WebSocket(wsUrl + '/' + id, {
- perMessageDeflate: false,
- });
- console.log(`The local ID is: ${id}`);
- console.log(`Waiting for signaling to be connected...`);
- ws.on('open', () => {
- console.log('WebSocket connected, signaling ready');
- readUserInput();
- });
- ws.on('error', (err) => {
- console.log('WebSocket Error: ', err);
- });
- ws.on('message', (msgStr) => {
- msg = JSON.parse(msgStr);
- switch (msg.type) {
- case 'offer':
- createPeerConnection(msg.id);
- pcMap[msg.id].setRemoteDescription(msg.description, msg.type);
- break;
- case 'answer':
- pcMap[msg.id].setRemoteDescription(msg.description, msg.type);
- break;
- case 'candidate':
- pcMap[msg.id].addRemoteCandidate(msg.candidate, msg.mid);
- break;
- default:
- break;
- }
- });
- function readUserInput() {
- rl.question('Enter a remote ID to send an offer: ', (peerId) => {
- if (peerId && peerId.length > 2) {
- rl.close();
- console.log('Offering to ', peerId);
- createPeerConnection(peerId);
- let msgToSend = randomId(MESSAGE_SIZE);
- for (let i = 1; i <= dataChannelCount; i++) {
- let dcArrItem = {
- dc: null,
- bytesSent: 0,
- bytesReceived: 0,
- };
- console.log('Creating DataChannel with label "test-' + i + '"');
- dcArrItem.dc = pcMap[peerId].createDataChannel('test-' + i);
- dcArrItem.dc.setBufferedAmountLowThreshold(BUFFER_SIZE);
- dcArrItem.dc.onOpen(() => {
- while (!disableSend && dcArrItem.dc.bufferedAmount() <= BUFFER_SIZE) {
- dcArrItem.dc.sendMessage(msgToSend);
- dcArrItem.bytesSent += msgToSend.length;
- }
- });
- dcArrItem.dc.onBufferedAmountLow(() => {
- while (!disableSend && dcArrItem.dc.bufferedAmount() <= BUFFER_SIZE) {
- dcArrItem.dc.sendMessage(msgToSend);
- dcArrItem.bytesSent += msgToSend.length;
- }
- });
- dcArrItem.dc.onMessage((msg) => {
- dcArrItem.bytesReceived += msg.length;
- });
- dcArr.push(dcArrItem);
- }
- // Report
- let i = 0;
- setInterval(() => {
- let totalBytesSent = 0;
- let totalBytesReceived = 0;
- for (let j = 0; j < dcArr.length; j++) {
- console.log(
- `${j == 0 ? i + '#' : ''} DC-${j + 1} Sent: ${byte2KB(
- dcArr[j].bytesSent,
- )} KB/s / Received: ${byte2KB(dcArr[j].bytesReceived)} KB/s / SendBufferAmount: ${dcArr[
- j
- ].dc.bufferedAmount()} / DataChannelOpen: ${dcArr[j].dc.isOpen()}`,
- );
- totalBytesSent += dcArr[j].bytesSent;
- totalBytesReceived += dcArr[j].bytesReceived;
- dcArr[j].bytesSent = 0;
- dcArr[j].bytesReceived = 0;
- }
- console.log(
- `Total Sent: ${byte2KB(totalBytesSent)} KB/s / Total Received: ${byte2KB(
- totalBytesReceived,
- )} KB/s`,
- );
- if (i % 5 == 0) {
- console.log(
- `Stats# Sent: ${byte2MB(pcMap[peerId].bytesSent())} MB / Received: ${byte2MB(
- pcMap[peerId].bytesReceived(),
- )} MB / rtt: ${pcMap[peerId].rtt()} ms`,
- );
- console.log(`Selected Candidates# ${JSON.stringify(pcMap[peerId].getSelectedCandidatePair())}`);
- console.log(``);
- }
- i++;
- }, 1000);
- }
- });
- }
- function createPeerConnection(peerId) {
- // Create PeerConnection
- let peerConnection = new nodeDataChannel.PeerConnection('pc', { iceServers: ['stun:stun.l.google.com:19302'] });
- peerConnection.onStateChange((state) => {
- console.log('State: ', state);
- });
- peerConnection.onGatheringStateChange((state) => {
- console.log('GatheringState: ', state);
- });
- peerConnection.onLocalDescription((description, type) => {
- ws.send(JSON.stringify({ id: peerId, type, description }));
- });
- peerConnection.onLocalCandidate((candidate, mid) => {
- ws.send(JSON.stringify({ id: peerId, type: 'candidate', candidate, mid }));
- });
- peerConnection.onDataChannel((dc) => {
- rl.close();
- console.log('DataChannel from ' + peerId + ' received with label "', dc.getLabel() + '"');
- let msgToSend = randomId(MESSAGE_SIZE);
- while (!disableSend && dc.bufferedAmount() <= BUFFER_SIZE) {
- dc.sendMessage(msgToSend);
- }
- dc.onBufferedAmountLow(() => {
- while (!disableSend && dc.bufferedAmount() <= BUFFER_SIZE) {
- dc.sendMessage(msgToSend);
- }
- });
- dc.onMessage((msg) => {
- // bytesReceived += msg.length;
- });
- });
- pcMap[peerId] = peerConnection;
- }
- function randomId(length) {
- var result = '';
- var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- var charactersLength = characters.length;
- for (var i = 0; i < length; i++) {
- result += characters.charAt(Math.floor(Math.random() * charactersLength));
- }
- return result;
- }
- function byte2KB(bytes) {
- return `${Math.round(bytes / 1000)}`;
- }
- function byte2MB(bytes) {
- return `${Math.round(bytes / (1000 * 1000))}`;
- }
|