Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eva-events

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eva-events

Eva is like an EventEmitter, but over WebSockets.

  • 0.2.1
  • Source
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

Image of Eve

eva-events

Eva is like an EventEmitter, but over WebSockets.

Features

  • Bidirectional EventEmitter over WebSockets
  • Very high performance (and memory efficient)
  • Messages can be between 10–60% smaller than JSON
  • You can send Date, Error, Buffer, RegExp, ArrayBuffer, TypedArray, Infinity, NaN, and of course everything that you can normally send with JSON. Magic!
  • Only 37 kB minified and gzipped
  • If you're already using bluebird (22 kB), and browserify's Buffer and EventEmitter (8 kB), then eva-events weighs in at only 7 kB extra

Basic usage

Client:

var Eva = require('eva-events')

var eva = new Eva('ws://myapp.com')

eva.on('hello world', function (msg) {
	console.log(msg) // "Hello world!"
	return new Date
})

Server:

var Eva = require('eva-events')

var app = Eva(server, function (eva) {
	eva.emit('hello world', 'Hello world!')
	.then(function (reply) {
		reply instanceof Date // true
		this === eva // true
	})
})
Explanation

On the client, .emit() triggers an event on the server. On the server, .emit() triggers an event on the client.

The .emit() method returns a promise which is resolved with the return value of the remote event listener. If an Error object is returned, the promise is rejected with that error.

Special reserved events

There are four special events you cannot .emit():

  • ready
  • done
  • killed
  • error

The ready event is triggered on a client when an open connection has been established and events may be sent back and forth.

The done event is triggered when the connection starts closing. After this event, neither party may emit new events. The connection will gracefully wait for pending transactions to finish before closing completely (unless there's an error or the connection is killed before then).

The killed event is triggered when the underlying connection has been completed closed. The first argument of this event is a boolean indicating if the connection was closed cleanly.

The error event is triggered when a fatal error occurs. This event will always kill the connection immediately after. This cannot be prevented. The first argument of this event is the associated error object.

Note: You cannot emit or listen to the newListener or removeListener events. Doing so will throw a SyntaxError.

Bad practices

Avoid these things when using eva-events:

Hanging transactions

If you .emit() an event before the other endpoint has registered a listener for that event, eva will wait for a response indefinitely. Other things can cause transactions to wait indefinitely too, such as poorly written application code. To prevent this, you can use .timeout() which causes all new transactions to fail and kill the connection if they aren't resolved after a certain amount of time. You should always listen on the killed event to react to these things accordingly.

Multiple listeners on the same event

If you have multiple listeners for the same event, the returned promise will only see the value returned by the first listener. In other words, each .emit() can only have one response. eva does not prevent you from having multiple listeners on the same event because that might sometimes be useful for applications making use of .send().

Browser compatibility

Much of Eva's awesomeness comes from her apt use of modern web technologies. She requires the Map object, and WebSocket with binary support (no legacy versions, only RFC-6455).

Natively, this package is supported by:

  • Chrome 38+
  • Firefox 13+
  • Safari 7.1+
  • Opera 25+
  • Internet Exporer 11+
  • Edge

However, if you polyfill Map you can support:

  • Chrome 16+
  • Firefox 11+
  • Safari 7+
  • Opera 12.1+
  • Internet Exporer 10+
  • Edge

API Reference

Class: Eva

On the client, these instances can be created by invoking the constructor:

var Eva = require('eva-events')
var eva = new Eva('ws://myapp.com/path/to/app')

On the server, these instances are exposed in the application handler (see EvaApplication).

.kill() -> this

Kills the connection. The done event is immediately emitted. All pending transactions are discarded. It may take some time for the underlying connection to actually close, so when it does, the killed event is emitted.

.done() -> this

Starts to gracefully end the connection. The done event is immediately emitted. Both endpoints will then wait for all pending transactions to be resolved before finally closing the underlying connection.

.emit(string eventName, [any data]) -> Promise

Starts a transaction by emitting an event to the opposite endpoint. That endpoint's listeners will be invoked with data as the first argument. The promise returned by this method is resolved when it receives a response back from a listener. If the response is an Error object, the promise is rejected with it, otherwise the promise is fulfilled with whatever data was sent back. Promises returned by this method, and promises chained from that promise, have a this value of the eva instance.

.send(string eventName, [any data]) -> this

This is the same as the .emit() method, except that it does not expect back a response. Anything returned by the event listener is discarded.

.on(string eventName, function listener) -> this

Registers an event listener listener for event eventName.

.addListener(string eventName, function listener) -> this

Alias for .on().

.once(string eventName, function listener) -> this

Same as .on(), but the listener will only be invoked once.

.removeListener(string eventName, function listener) -> this

Unregisters a listener listener that has been registered with event eventName.

.removeAllListeners([string eventName]) -> this

Unregisters all event listeners on the instance, or all listeners of event eventName.

.listenerCount(string eventName) -> number

Returns the number of event listeners that are registered with event eventName.

.timeout(number sec) -> this

Causes all future transactions to timeout after sec seconds, at which point an error event will be emitted and the connection will be forcefully killed. A sec value of 0 or Infinity turns off timeouts.

Default: 0

.killTimeout(number sec) -> this

Sets how long eva will wait to gracefully end the connection, before timing out and forcefully killing it. A sec value of 0 or Infinity indicates that eva will wait forever.

Default: 30

get .isReady -> boolean

Indicates if the connection is open and events may be sent back and forth.

get .bufferedAmount -> number

Returns the number of bytes in the internal buffer. In advanced applications, this can be monitered to adjust network usage rates.

Class: EvaApplication

On the server:

var Eva = require('eva-events')
var app = Eva(server, '/path/to/app', function (eva) {
	eva.emit('welcome', 'Welcome to my app.')
})
constructor EvaApplication(http.Server server, [string path], [function handler, [function verifyClients]])

Also supports https (thus, wss://) servers.

You may supply a verifyClients function which must return true for each client wishing to connect to the WebSocket server. The function may have the following two signatures:

function verifyClients(info) { // synchronous
	return false
}
function verifyClients(info, cb) { // asynchronous
	cb(false, 401, 'Unauthorized')
}

info is an object with the following properties:

  • string origin
  • boolean secure
  • http.IncomingMessage req

path defaults to "/"

.addHandler(function handler) -> this

Registers handler to be invoked for each new client connection that is made. This is the same as passing a handler argument to the EvaApplication constructor. You may have multiple handlers.

.removeHandler(function handler) -> this

Unregisters a function handler. This is the opposite of .addHandler().

.currentClients() -> Array

Returns a snapshot array of the current eva clients that are connected.

.kill() -> this

Starts to close down this EvaApplication by rejecting all new clients trying to connect, and by invoking the .kill() method on each connected client.

.done() -> this

Starts to close down this EvaApplication by rejecting all new clients trying to connect, and by invoking the .done() method on each connected client.

.broadcast(string eventName, [any data]) -> this

Invokes the .send() method on each client that isReady.

License

MIT

Keywords

FAQs

Package last updated on 22 Jan 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc