Skip to content

Enriched (with features) UDP Socket and Client. Encryption. Big data. CJS & ESM

License

Notifications You must be signed in to change notification settings

JerryCauser/e-socket-udp

Repository files navigation

Enriched UDP Socket and Client

npm tests CodeQL CodeFactor Grade JavaScript Style Guide node-current GitHub

Enriched UDP Socket and Client with possibility to encrypt data and send big messages.

  • Fast — small overhead above UDP to send messages
  • Secure — built-in encryption for sensitive logs
  • Universal – built-in fragmentation to send big messages
  • Simple — used well-known Node streams to manipulate and move data
  • ESM and CJS

Install

npm i --save e-socket-udp

Fast Start

//client.js
import { UDPClient } from 'e-socket-udp'

const secret = '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
const client = new UDPClient({ encryption: secret })

client.write(Buffer.from('Hello, World!', 'utf8'))
//server.js
import { UDPSocket } from 'e-socket-udp'

const secret = '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
const socket = new UDPSocket({ decryption: secret })

for await (const message of socket) {
  console.log(message)
}

After just start the server node server.js and client node app.js. That's all and everything works.

Documentation

class UDPClient

Extends Basic UDPClient.

Arguments:

  • options <object> – optional
    • type <'udp4' | 'udp6'> – optional. Inherited. Default 'udp4'
    • port <string | number> – optional. Inherited. Default 44302
    • address <string> – optional. Inherited. Default '127.0.0.1' or '::1'
    • encryption <string> | <(payload: Buffer) => Buffer> – optional. Default undefined
      • if passed string - will be applied aes-256-ctr encryption with passed string as a secret, so it should be 64char long;
      • if passed function - this function will be used to encrypt every message;
      • if passed undefined - will not use any kind of encryption.
    • fragmentation <boolean> – optional. Automatically split each message into chunks. Useful with any size of messages (especially big ones). Default true
    • packetSize <number> – optional. Used if fragmentation = true. Number of bytes in each packet (chunk). Default 1280

Methods:

  • write (buffer): <boolean>Inherited.

Fields:

  • origin: <dgram.Socket>Inherited.
  • port: <number>Inherited.
  • address: <string>Inherited.
  • family: <string>Inherited.

Events:

  • 'ready': <void>Inherited. Emitted when the client "establishes" udp connection.

Usage

Simple example with encryption
import { UDPClient } from 'e-socket-udp'

const client = new UDPClient({
  port: 44302,
  // encryption: (buf) => buf.map(byte => byte ^ 83)
  encryption: '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
})

client.write(Buffer.from('Hello, world!', 'utf8'))

class UDPSocket

Extends Basic UDPSocket

It is a UDP socket in readable stream form with encoding and possibility to handle big messages.

Arguments:

  • options <object>required
    • type <'udp4' | 'udp6'> – optional. Inherited. Default 'udp4'
    • port <string | number> – optional. Inherited. Default 44302
    • host <string> – optional. Inherited. Default '127.0.0.1' or '::1'
    • decryption <string> | <(payload: Buffer) => Buffer> – optional. Default undefined
      • if passed string - will be applied aes-256-ctr decryption with passed string as a secret, so it should be 64char long;
      • if passed function - will be used that function to decrypt every message;
      • if passed undefined - will not use any kind of decryption.
    • fragmentation <boolean> – optional. Combine chunks into message. Useful with any size of messages (especially big ones). Default true
    • gcIntervalTime <number> — optional. How often instance will check internal buffer to delete expired messages (in ms). Default 5000
    • gcExpirationTime <number>— optional. How long chunks can await all missing chunks in internal buffer (in ms). Default 10000

Fields:

  • origin: <dgram.Socket>Inherited.
  • port: <number>Inherited.
  • address: <string>Inherited.
  • family: <string>Inherited.
  • allowPush: <boolean>Inherited.

Events:

All Readable events of course and:

Event: 'ready'Inherited.

Emitted when socket started and ready to receive data.

Event: 'warning'

Emitted when warning occurs.

  • message <object | Error>
    • type <Symbol>
    • id <string> – optional
    • date <Date> – optional

A type might be:

  • Symbol<'missing_message'> – when some messages didn't receive all chunks and got expired.
  • Symbol<'decryption_message'> – when some messages failed to be compiled from chunks.

Usage

Example how to use pure socket as async generator
import { UDPSocket } from 'e-socket-udp'

const socket = new UDPsocket({
  port: 44302,
  // decryption: (buf) => buf.map(byte => byte ^ 83) // not safe at all, but better than nothing
  decryption: '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
})

for await (const message of socket) {
  /*handle messages*/
}
Example how to use socket and fs write stream
import fs from 'node:fs'
import { UDPSocket } from 'e-socket-udp'

const secret = '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'

const writer = fs.createWriteStream('/some/path')
const socket = new UDPSocket({ port: 44302, decryption: secret })

socket.pipe(writer)

Additional Exposed variables and functions

constant DEFAULT_PORT

  • <number> : 44302

constant WARNING_MISSING_MESSAGE

  • <Symbol> : Symbol<'missing_message'>

constant WARNING_DECRYPTION_FAIL

  • <Symbol> : Symbol<'decryption_fail'>

There are _identifier and _constants exposed also, but they are used for internal needs. They could be removed in next releases, so it is not recommended to use it in your project.


License (MIT)