Comparing version 0.1.0 to 0.1.1
@@ -5,2 +5,4 @@ 'use strict'; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
var _quic = require('quic'); | ||
@@ -16,19 +18,2 @@ | ||
// quic.listen(2345) // also takes address, defaults to localhost | ||
// .then(() => {}) | ||
// .onError(error => {}) | ||
// .onData((data, stream) => {}) | ||
// // stream has .write() function | ||
// quic.stopListening() | ||
// .then(() => {}) | ||
// quic.getServer() // low level server object | ||
// quic.getClient() // low level client object | ||
// quic.getAddress() // { port: number,family:string (like "IPv4"),address: string (ip address) } | ||
// quic.send(url, data) | ||
// .onError(error => {}) | ||
// .onData(data => {}) | ||
// simple convenience helper | ||
@@ -39,2 +24,15 @@ var rejectPromise = function rejectPromise(promise, err, message) { | ||
// the underlying quic library can only handle strings or buffers. | ||
// This is used to convert to one of them. | ||
var convertToSendType = function convertToSendType(data) { | ||
// buffers should be sendable | ||
if (Buffer.isBuffer(data)) return data; | ||
// objects must be stringified | ||
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') return JSON.stringify(data); | ||
// all else should be strings | ||
return data; | ||
}; | ||
var Quic = function () { | ||
@@ -65,2 +63,3 @@ function Quic() { | ||
var message = ''; | ||
var buffer = void 0; | ||
@@ -71,11 +70,14 @@ stream.on('error', function (err) { | ||
message += data.toString(); | ||
if (buffer) buffer = Buffer.concat([buffer, data]);else buffer = data; | ||
}).on('end', function () { | ||
var oldWrite = stream.write.bind(stream); | ||
stream.write = function (data) { | ||
if (typeof data !== 'string') data = JSON.stringify(data); | ||
oldWrite(data); | ||
var convertedData = convertToSendType(data); | ||
oldWrite(convertedData); | ||
stream.end(); | ||
}; | ||
promise.handleData(message, stream); | ||
}).on('finish', function () {}); | ||
promise.handleData(message, stream, buffer); | ||
}); | ||
}); | ||
@@ -108,3 +110,2 @@ }); | ||
value: function send(port, address, data) { | ||
// TODO change port, address to address:port? | ||
var promise = new _arbitraryPromise2.default([['resolve', 'then'], ['reject', 'onError'], ['handleData', 'onData']]); | ||
@@ -114,9 +115,13 @@ | ||
if (typeof data !== 'string') data = JSON.stringify(data); | ||
var convertedData = convertToSendType(data); | ||
var client = new _quic.Client(); | ||
client.on('error', function (err) { | ||
rejectPromise(promise, err, 'client error'); | ||
}); | ||
// These clients are ephemeral so we'll nuke em when they're done | ||
client.on('close', function () { | ||
client.destroy(); | ||
return client.destroy(); | ||
}); | ||
@@ -129,2 +134,3 @@ | ||
var message = ''; | ||
var buffer = void 0; | ||
@@ -135,8 +141,9 @@ stream.on('error', function (err) { | ||
message += data.toString(); | ||
if (buffer) buffer = Buffer.concat([buffer, data]);else buffer = data; | ||
}).on('end', function () { | ||
client.close(); | ||
promise.handleData(message); | ||
}).on('finish', function () {}); | ||
promise.handleData(message, buffer); | ||
}); | ||
stream.write(data, function () { | ||
stream.write(convertedData, function () { | ||
promise.resolve(); | ||
@@ -143,0 +150,0 @@ stream.end(); |
{ | ||
"name": "node-quic", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"description": "A wrapper around fidm/quic, node-quic is a dead simple stream based QUIC server / client for use in node.js.", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
@@ -36,10 +36,15 @@ # node-quic | ||
.onData((data, stream) => {}) // data here will be whatever was sent using quic.send(), | ||
// and stream will have to function properties: | ||
// `write` and `end.` Use stream.write(data) to return | ||
// information to the original sender. Note: stream.write | ||
// will automatically stringify any data sent to it, but | ||
// you will need to parse your own data on the way out of | ||
// `.onData` for `quic.listen` and for `quic.send`. | ||
// Use `stream.end()` if you don't need to send anything back. | ||
.onData( | ||
(data, stream, buffer) => {} | ||
) // data here will be a stringified version of | ||
// whatever was sent using quic.send(), stream will have | ||
// two function properties: `write` and `end.` | ||
// Use stream.write(data) to return information to the | ||
// original sender. Note: stream.write will automatically | ||
// stringify any non-buffer data sent to it, but you will need | ||
// to parse your own data on the way out of `.onData` for | ||
// `quic.listen` and for `quic.send`. Use `stream.end()` | ||
// if you don't need to send anything back. If you are working | ||
// with buffers directly and don't need anything stringified, | ||
// you can use the buffer argument. | ||
@@ -54,4 +59,5 @@ quic.send(port, address, data) // Send data to a listening server. `data` is automatically | ||
.onData((data) => {}) // data is populated by whatever the receiving server deems | ||
// necessary to send back. | ||
.onData((data, buffer) => {}) // `data` is populated by whatever the receiving server deems | ||
// necessary to send back. `buffer` contains the unstringified | ||
// version of the data. | ||
``` | ||
@@ -58,0 +64,0 @@ |
@@ -22,5 +22,2 @@ /* | ||
// TODO: | ||
// * Add mean after extreme removal | ||
import quic from '../src/index' | ||
@@ -33,2 +30,3 @@ import express from 'express' | ||
import WebSocket from 'ws' | ||
import net from 'net' | ||
@@ -44,3 +42,3 @@ // How many servers / clients do we want to spin up? | ||
const DATA_SIZE = process.env.DATA_SIZE || '0' | ||
const DATA_SIZE = Number(process.env.DATA_SIZE) || 0 | ||
@@ -60,4 +58,24 @@ // get a nice specific timestamp | ||
const runAsServer = (quicPort, httpPort, wsPort) => { | ||
// return a random character | ||
const _randomChar = () => { | ||
return 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n' | ||
.split('')[Math.round(Math.random() * 62)] | ||
} | ||
// create some data of the specified size (in kb) | ||
// note if 0 is specified, a short string will be returned | ||
const _createData = size => { | ||
if (size === 0) return 'Here\'s the data!' | ||
let data = '' | ||
for (let i = 0; i < size * 1000; i++) { | ||
data += _randomChar() | ||
} | ||
return data | ||
} | ||
const runAsServer = (quicPort, httpPort, wsPort, netPort) => { | ||
// The quic server | ||
@@ -91,6 +109,27 @@ quic.listen(quicPort, ADDRESS) | ||
wss.on('connection', ws => ws.on('message', ws.send)) // bounce it back | ||
const server = net.createServer({ allowHalfOpen: true }, socket => { | ||
socket.on('error', console.error.bind(null, 'net error:')) | ||
let data | ||
socket.on('data', dat => { | ||
if (data) data = Buffer.concat([data, dat]) | ||
else data = dat | ||
}) | ||
socket.on('end', () => { | ||
socket.write(data, () => { | ||
socket.end() | ||
}) | ||
}) | ||
}) | ||
server.listen(netPort, ADDRESS, () => { | ||
console.log(`net server listening at:${ADDRESS}:${netPort}`) | ||
}) | ||
} | ||
const runAsClient = (quicPort, httpPort, wsPort) => { | ||
const data = fs.readFileSync(path.resolve(__dirname, `data/${DATA_SIZE}kb`), { encoding: 'utf8' }) | ||
const runAsClient = (quicPort, httpPort, wsPort, netPort) => { | ||
const data = _createData(DATA_SIZE) | ||
@@ -101,3 +140,3 @@ const quicPromise = new Promise((resolve, reject) => { | ||
quic.send(quicPort, ADDRESS, data) | ||
.onError(console.error) | ||
.onError(reject) | ||
.onData(resp => { | ||
@@ -118,2 +157,3 @@ if (resp !== data) reject('QUIC received wrong response') | ||
}, (err, resp) => { | ||
if (err) return reject(err) | ||
resp = resp.body | ||
@@ -131,2 +171,3 @@ if (resp !== data) reject('HTTP received wrong response') | ||
ws.on('open', () => ws.send(data)) | ||
ws.on('error', reject) | ||
ws.on('message', message => { | ||
@@ -139,3 +180,33 @@ if (message !== data) reject('WS received wrong response') | ||
return Promise.all([quicPromise, httpPromise, wsPromise]) | ||
const netPromise = new Promise((resolve, reject) => { | ||
const client = new net.Socket() | ||
const start = _getTime() | ||
client.on('error', reject) | ||
client.on('close', () => client.destroy()) | ||
let buffer | ||
client.on('data', dat => { | ||
if (buffer) buffer = Buffer.concat([buffer, dat]) | ||
else buffer = dat | ||
}) | ||
client.on('end', () => { | ||
if (buffer.toString() !== data) return reject('net received wrong response') | ||
resolve(_getTime() - start) | ||
client.destroy() | ||
}) | ||
client.connect(netPort, ADDRESS, () => { | ||
client.write(data, () => { | ||
// console.log('client has finished write') | ||
client.end() | ||
}) | ||
}) | ||
}) | ||
return Promise.all([quicPromise, httpPromise, wsPromise, netPromise]) | ||
} | ||
@@ -196,2 +267,8 @@ | ||
async function _sleep (duration) { | ||
return new Promise(resolve => { | ||
setTimeout(resolve, duration) | ||
}) | ||
} | ||
const _formatTimings = timings => { | ||
@@ -201,2 +278,3 @@ const quicResponses = timings.map(timingPair => Number(timingPair[0])) | ||
const wsResponses = timings.map(timingPair => Number(timingPair[2])) | ||
const netResponses = timings.map(timingPair => Number(timingPair[3])) | ||
@@ -206,6 +284,8 @@ const sortedQuicResponses = _sort(quicResponses) | ||
const sortedWSResponses = _sort(wsResponses) | ||
const sortedNetResponses = _sort(netResponses) | ||
const trimmedQuicResponses = _withoutExtremes(quicResponses) | ||
const trimmedHttpResponses = _withoutExtremes(httpResponses) | ||
const trimmedWSResponses = _withoutExtremes(wsResponses) | ||
const trimmedQuicResponses = _withoutExtremes(sortedQuicResponses) | ||
const trimmedHttpResponses = _withoutExtremes(sortedHttpResponses) | ||
const trimmedWSResponses = _withoutExtremes(sortedWSResponses) | ||
const trimmedNetResponses = _withoutExtremes(sortedNetResponses) | ||
@@ -215,2 +295,3 @@ const quicMean = _calculateMean(trimmedQuicResponses) | ||
const wsMean = _calculateMean(trimmedWSResponses) | ||
const netMean = _calculateMean(trimmedNetResponses) | ||
@@ -220,2 +301,3 @@ const quicMedian = _calculateMedian(trimmedQuicResponses) | ||
const wsMedian = _calculateMedian(trimmedWSResponses) | ||
const netMedian = _calculateMedian(trimmedNetResponses) | ||
@@ -225,2 +307,3 @@ const quicHigh = _calculateHigh(trimmedQuicResponses) | ||
const wsHigh = _calculateHigh(trimmedWSResponses) | ||
const netHigh = _calculateHigh(trimmedNetResponses) | ||
@@ -230,2 +313,3 @@ const quicLow = _calculateLow(trimmedQuicResponses) | ||
const wsLow = _calculateLow(trimmedWSResponses) | ||
const netLow = _calculateLow(trimmedNetResponses) | ||
@@ -235,2 +319,3 @@ const quicStdDev = _calculateStdDev(trimmedQuicResponses) | ||
const wsStdDev = _calculateStdDev(trimmedWSResponses) | ||
const netStdDev = _calculateStdDev(trimmedNetResponses) | ||
@@ -240,2 +325,3 @@ const quicHighFive = _getHighFive(sortedQuicResponses) | ||
const wsHighFive = _getHighFive(sortedWSResponses) | ||
const netHighFive = _getHighFive(sortedWSResponses) | ||
@@ -245,2 +331,3 @@ const quicLowFive = _getLowFive(sortedQuicResponses) | ||
const wsLowFive = _getLowFive(sortedWSResponses) | ||
const netLowFive = _getLowFive(sortedWSResponses) | ||
@@ -253,23 +340,31 @@ const ret = { | ||
wsResponses: JSON.stringify(trimmedWSResponses), | ||
netResponses: JSON.stringify(trimmedNetResponses), | ||
quicMean, | ||
httpMean, | ||
wsMean, | ||
netMean, | ||
quicMedian, | ||
httpMedian, | ||
wsMedian, | ||
netMedian, | ||
quicHigh, | ||
httpHigh, | ||
wsHigh, | ||
netHigh, | ||
quicLow, | ||
httpLow, | ||
wsLow, | ||
netLow, | ||
quicStdDev, | ||
httpStdDev, | ||
wsStdDev, | ||
netStdDev, | ||
quicHighFive, | ||
httpHighFive, | ||
wsHighFive, | ||
netHighFive, | ||
quicLowFive, | ||
httpLowFive, | ||
wsLowFive | ||
wsLowFive, | ||
netLowFive | ||
} | ||
@@ -284,7 +379,10 @@ | ||
for (let p = START_PORT; p < START_PORT + NUM_SPINUPS; p++) { | ||
for (let p = START_PORT; p < START_PORT + (NUM_SPINUPS * 4); p += 4) { | ||
const [ quicPort, httpPort, wsPort, netPort ] = [p, p + 1, p + 2, p + 3] | ||
if (isClient) { | ||
responsePromises.push(runAsClient(p, p + NUM_SPINUPS, p + (NUM_SPINUPS * 2))) | ||
responsePromises.push(runAsClient(quicPort, httpPort, wsPort, netPort)) | ||
await _sleep(300) // without this, we start seeing QUIC_NETWORK_IDLE_TIMEOUT errors on the server | ||
} | ||
else runAsServer(p, p + NUM_SPINUPS, p + (NUM_SPINUPS * 2)) | ||
else runAsServer(quicPort, httpPort, wsPort, netPort) | ||
} | ||
@@ -291,0 +389,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
419
82
40396
10