Truflux uses a separate protocol definition module. No internal messaging module is provided.Here are some official definition modules
truflux-msg A stateless messaging protocol.Very easy to use. https://www.npmjs.com/package/truflux-msg
truflux-state-msg A stateful messaging protocol.Recommended for intermediate use. https://www.npmjs.com/package/truflux-state-msg
TL:DR
Truflux is a lightweight high performance socket framework for protocol based messaging for websockets and netsockets supporting read/write streams to allow you to send files across a network, as well as crypto for symmetric and asymmetric secure connections.The browser client is about ~5kb minified and ~2kb gzipped.
For some recipes on common networking actions see the end of the readme. This includes file sending and binding to servers like express .Note that the browser client contains the same functionality as a net client, but has a few small differences which are outlined below
$3
The current performance stats are based on the benchmarking test performed by ws, the current "fastest" socket library
These number are performed on a lowend 32bit laptop with 1.3GHz CPU with 1GB RAM which is actually inferior to the m3.xlarge EC2 instance that ws uses for testing.
NOTE With a standard 3.2GHz CPU, you can expect a speed increase of about 8x
However as you can see, we soundly beat the current benchmark of 'ws' performance even with the overhead of crypto.
#### truflux
No crypto
* Running 10000 roundtrips of 64 B binary data: 3.8s 185.96 kB/s
* Running 5000 roundtrips of 16 kB binary data: 3.9s 23.85 MB/s
* Running 1000 roundtrips of 128 kB binary data: 4.5s 36.62 MB/s
* Running 100 roundtrips of 1 MB binary data: 5.2s 21.21 MB/s
* Running 10 roundtrips of 10 MB binary data: 24.4s 4.71 MB/s
Crypto using aes-256-cbc
* Running 10000 roundtrips of 64 B binary data: 4.9s 126.9 kB/s
* Running 5000 roundtrips of 16 kB binary data: 9.1s 8.56 MB/s
* Running 1000 roundtrips of 128 kB binary data: 13.2s 9.49 MB/s
* Running 100 roundtrips of 1 MB binary data: 13.8s 7.27 MB/s
* Running 10 roundtrips of 10 MB binary data: 31s 3.22 MB/s
#### ws
* Running 10000 roundtrips of 64 B binary data: 22.1s 28.34 kB/s
* Running 5000 roundtrips of 16 kB binary data: 33.9s 2.31 MB/s
* Running 1000 roundtrips of 128 kB binary data: 50s 2.5 MB/s
* Running 100 roundtrips of 1 MB binary data: 35.3s 2.83 MB/s
* Running 10 roundtrips of 10 MB binary data: 35s 2.85 MB/s
We can improve this performance drastically for large files once Node / iojs increase the tcp window size to do more efficient chunking of the buffers
NOTE also that truflux does not use unix sockets to circumvent the network interface to artificially inflate its speed.
$3
`js
var tru=require('truflux');
var msg=require('truflux-msg');
var protocol=new msg();
protocol.add('echo',function(data,sock)
{sock.send('display',data);})
.add('display',function(data)
{console.log(data);});
var server=new tru.Server({msg:protocol});
server.open();
var client=new tru.Client({msg:protocol}))
client.open().on('open',function(sock)
{
sock.send('echo','Atreyuuuu!');
});
`
$3
See the following gist on how to create a minimal server/client messenger for truflux in 75 lines with extensible protocol,broadcasting
and oldschool prompt interface
https://gist.github.com/Auxolust/59d13b5f070b5717fa58
$3
* An upcoming CDN will be provided to allow lightning fast downloads of the browserclient. This will be the recommended action to using truflux in the browser
* UDP protocol for real time streaming (This will most likely be its own package to prevent bloat)
* Message chunk limiter for production servers
* Currently the server does not encrypt blob chunks when it sends data from the server to browserclient. This will be rectified via utf-8 encoding , however there will obviously be a large performance penalty on the client side to perform deciphering which I will address as soon as I can.
* Automatic symmetric key randomisation every x amount of time to prevent cracking the socket security. This will create a pessimistic estimate of the time required by a malicious hacker to bruteforce their way past the symmetric key and automatically randomize the key
$3
$3
Major overhaul. Everything was rewritten with the exception of the security and standard files. Needless to say this mandated a major update.
New changes include more concise language, as well as the adoption of traits internally to prevent the performance overhead of function stacks.
The most prevalent of these changes is the abstraction between websockets and netsockets and the new support for http servers
#### V1.0.0
Modified the ID to use the Pseudo-Hadamard transform as an isomorphic map for the ID when in secure mode. This is the first step to allowing one to plug their own cipher into the endpoints.
As a result of this the fixed header size is down to 72 bits in both secure and unsecure mode, reducing header size in secure mode by 57%.This replaces the old aes-256-cbc ciphering of the message ID which was slow and inefficient.The new PHT function results in an average 1.132 microsecond decryption and encryption
Modified file sending to send as binary type, this has reduced file sending size by ~69% on average
Also added in asymmetric security and expose the cipher type to allow custom encryption on the channels if needed
The change in the underlying architecture to changing the security has mandated a v1.0.0 increase to avoid breaking changes with old non asymmetric channels
#### V0.3.0
Added support to pausing and resuming network streams. We now default to sending buffer based encoding when sending files to avoid mangling binary files so you can now send .exes etc through the network.
Also modified server broadcast to allow passing in an array of excluded sockets we don't want to receive the broadcasted message
#### V 0.2.0
Now using fixed header sizes and preferring binary type buffer data
##### Old Dynamic messages
256 bits Minimal message size in unsecure mode
592 bits Minimal message size in secure mode
##### New fixed headers
9 Octet header size per message in unsecure mode = 72 bits
21 Octet header size per message in secure mode = 168 bits
Average message size is now down 77%
We now support 2147483647 unique message types as well as a theoretical single message maximal size of 31.2 Gb. However we highly suggest streaming for large volume data exchange. Added support to pipe to/from streams when sending files across the network.Encryption has been upgraded from aes-192-cbc to aes-256-cbc.
Performance for pushing out messages has degraded by 0.9% based on sending 1000 messages of varying types, this is in response to buffer packing, as the performance of buffers only truly shines with larger message types.To see the current stats
of pushing out messages, see the bottom of the page
We've now changed from recursive descent parsing of the the message parsing to an iterative approach, so you cannot blow the call stack by pushing too many messages too fast
API
There are 4 objects exposed when you require truflux
` Server //The object to create a new server with
Client //The object to create a new client with
std //A collection of standards, such as default system messages as well as an enumeration of errors.These will not be changed with the exception of major version updates, so feel free to use
httpBind //A function to bind a truflux server to an http server
`
httpBind(trufluxServer,httpServer,options)
Used to bind an http server to allow websockets to interact with the truflux server
`text
options:
{
path: String Relative path on the http server for the binding. An error WILL be thrown if you attempt to bind two truflux servers to the same path. DEFAULT='/'
}
`
`text
options:
{
port: Integer
msg: Truflux-msg Object
ciphers: String or Array of Strings. A list in priority order of the cipher type you wish to you to connect to a client. DEFAULT aes-256-cbc
noDelay: Whether to turn off message buffering according to Nagles algorithm. Default is false to reduce network congestion
}
`
$3
Opens the server and starts listening. CHAINABLE
`text
cb : callback function
`
$3
Manually adds a socket object to the server. This socket must adhere to the standard tcp socket interface. You will probably never have to call this yourself
` options:
{
port: Integer
msg: Truflux-msg Object
ciphers: String or Array of Strings. A list in priority order of the cipher type you wish to you to connect to a client. DEFAULT aes-256-cbc
noDelay: Whether to turn off message buffering according to Nagles algorithm. Default is false to reduce network congestion
}
`
$3
Closes the server .CHAINABLE
`text
cb : callback function
force : Whether to force closing or end gracefully
`
$3
Broadcasts a message to currently connected server-clients , see Common client's send function for more info on id and data.CHAINABLE
`text
id: String | Integer
data: Any
exclude: Client| Array of Clients
`
$3
Returns the number of currently connected clients
$3
* client Emitted on new connection from a client
`js
function(client)
`
* error Emitted on server error. One such possible error would be if the client does not support the required cipher type
`js
function(stdError,clientIfApplicable)
`
The stdError Object is as follows
`text
{
e:The error code.Error codes are available from sec.std.errors
add:An OPTIONAL value that is passed in from some error codes
}
`
Common Client
These methods are common to any client, server-client,websocket client or the net client.
$3
`text
session: An object that can be used to store session variables if needed
`
$3
These events are common to both server-client and standard client
* error Emitted when an error occurs on a client
`js
function(stdErrorObject,client)
`
* file Emitted when a file is offered for download
`js
function(NetworkFileWriter,client)
`
* close emitted the client closing
`js
function(stdErrorObject,client)
`
$3
Sends a message to across the network to the peer.Internally a call to a checkStructure function will be called by the client to check if the message adheres to the schema set out in the message definition .CHAINABLE
`text
id : String/Integer
data : Any. Any data you send will return on the other side with the correct type intact. Objects will be objects, buffers will be buffers, etc
`
`js
client.send(trufluxMsgObject.id.echo,"Do you want messages? Because that's how you get messages");
// OR
client.send("echo","Um phrasing? Are we still doing that?");
`
$3
Returns a NetworkFileReader object and starts sending a file to the peer.See NetworkFileReader for more details
`text
Reader: String for a filepath ||Readable stream that will have its input piped in and sent
options :
{
name :String If string filepath is provided for reader this is not required , defaults to "[Stream]" for streams
type:String, Stream transport type ,hex,base64 etc USELESS IN BROWSER
size:number If string filepath is provided for reader this is not required to be set ,-1 for streams is the default
}
`
$3
Closes the connection and sends a message to the peer to know the connection was closed cleanly, if no force was applied.CHAINABLE
`text
force: Boolean , whether to force close the socket connection or to send a message saying it was closed cleanly
`
$3
Retrieves the socket info.Returns the following.
`text
address:String, the local address
port:Integer, the local port
remoteAddress:String,
remotePort:Integer
`
Server-client
There are 3 readOnly properties.The first 2 are used to see the current security status. Truflux allows asymmetric encryption
` secure //Boolean Whether we are encrypting our data
peerSecure //Boolean Whether our peer is encrypting their data
ws //Boolean Whether or not the connections is a websocket
`
$3
Turns the security of the stream from client->serverClient on/off.Turning security off has performance gains as we don't have to encrypt messages.CHAINABLE
`text
enabled: Boolean
`
$3
Turns the security of the stream from serverClient->client on/off.Turning security off has performance gains as we don't have to encrypt messages.CHAINABLE
`text
enabled: Boolean
`
Client
$3
options Object
`text
{
port: Number USELESS FOR BROWSER CLIENTS
host: String
msg: Truflux-msg Object,
noDelay: Whether to turn off message buffering according to Nagles algorithm USELESS FOR BROWSER CLIENTS
crypto: Crypto module for BROWSER CLIENTS. Allows modular security
}
`
$3
Connects to the server specified on host : port . CHAINABLE
$3
#### Events in Browser
NOTE the browser implementation does not utilize eventEmitters. It instead exposes functions as properties
` onClose=function()
onOpen=function()
onErr=function(err)
`
#### EventEmitter events for non-browser
* open Emitted when the client has connected to the server and communication can occur.The client is now ready to use
`js
function(client)
`
NetworkFileReader
An object this is provided when calling client.sendFile()
$3
#### Events in Browser
NOTE the browser implementation does not utilize eventEmitters. It instead exposes functions as properties
` onEnd=function()
onAccept=function()
onCancel=function()
onPause=function()
onResume=function()
onDecline=function()
`
#### EventEmitter events for non-browser
* accept Emitted when the peer has accepted the offered file for download.
`js
function(NetworkFileReader,client)
`
* error
`js
function(NetworkFileReader,client)
`
* decline Emitted when the peer has declined the proffered file
`js
function(NetworkFileReader,client)
`
* pause Emitted when the peer has paused the proffered file
`js
function(NetworkFileReader,client)
`
* resume Emitted when the peer has resumed download of the proffered file
`js
function(NetworkFileReader,client)
`
* finish Emitted when the peer has finished downloading the entire file
`js
function(NetworkFileReader,client)
`
* cancel Emitted when the peer has cancelled the download of the file
`js
function(NetworkFileReader,client)
`
NetworkFileWriter
An object that is provided on the file event of the CommonClient
There are a few publicly accessible properties you might find helpful
` name //String Name of the sent file
size //Integer Size in bytes of the file
isStream//Boolean whether or not its a stream
paused //whether or not the filewriter is paused. Check for truthyness on the BROWSER CLIENT
`
$3
Accepts an offered file over the network and starts stream writing it to the specified Writer
` acceptor:String for filepath | writable stream that will have the input piped to it
NOTE The browser client does not have an acceptor argument
`
$3
Declines an offered network file
$3
Cancels the file download if previously accepted
$3
Pauses the file download
$3
Resumes the file download
$3
#### Events in Browser
NOTE the browser implementation does not utilize eventEmitters. It instead exposes functions as properties
` onEnd=function(blobDataURI)
onErr=function(err)
`
#### EventEmitter events for non-browser
* error
`js
function(stdErrObject,NetworkFileWriter,client);
` * end Emitted when the stream has finished writing the object to file
`js
function(NetworkFileWriter,client)
`
$3
* The browserClient for truflux does not contain the server,httpbind or std objects
* Compatibility is always a problem with browsers. By default truflux exports all its properties into the window namespaced as an object called truflux .This has the following properties
`text
window.truflux=
{
Client:Function,//The client constructor to create a new client
fileDown:Boolean,//Whether file downloads are possible
fileUp:Boolean //Whether file uploads are possible
};
`
* When sending files between net sockets, they are automatically encrypted. The current performance penalty in the browser means I have yet to implement it, so be awares that on a non wss:// socket files might be sniffed
* Since its wrapped in a function for the import, no errors should be throw if websockets are not supported, however I urge you to use !!window.WebSocket to check if websockets are supported
* The browser does not contain crypto within it. Therefore having a server that uses a secure channel will cause a failSecure event to be emitted on the server client
In order to enable crypto in the browser, the crypto module must provide the following functionality in compliance with standard node/iojs crypto functionality
var sender=browserClient.sendFile(someFileObject);
sender.onAccept=function()
{
console.log('Our file upload offer was accepted');
}
sender.onEnd=function()
{
console.log('The server has our file');
}
`
#### Receiving a file as a browser client
`js
browserClient.onFile=function(wstream)
{
wstream.accept();
wstream.onEnd=function(uri)
{
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
//Remove URL if you're not using it anymore
window.URL.revokeObjectURL(uri);
}
}
`
#### Upgrading to a symmetric secure connection
`js
//Assuming this is the first time we've called it
serverClient.setOwnSecurity(true)
.setClientSecurity(true)
.once('handshaked',function()
{
console.log(socket.secure);//true
console.log(socket.peerSecure);/*Not necessarily true until truflux gets the client acknowledgement,
however the client will receive the setSecurity message before this so synchronicity is conserved*/
//Once the initial handshake happens, there is no need to listen anymore ie
//No need to listen to the handshake anymore, we just flip the security on and off from here
serverClient.setOwnSecurity(false)
.setOwnSecurity(true)
.setClientSecurity(false)
.setClientSecurity(true)
.send('someMessage',someData);
}).once('failSecure',function()
{
//Client probably does not have the supported ciphers.Lets kick him off
serverClient.close();
};
``