harpy rpc
not stable.
harpy is a bidirectional rpc system for node, glued together with json-rpc and a promise-based workflow.
getting started
to create a websocket-server (using ws):
// server// note: using babel is optional, but more fun.;harpywebSocket;
and a corresponding client:
// client;{let client = await harpywebSocket;let doubled = await client;console;// doubling 5 gives 10! amazing!};
server to client communication
the client can also call describe to send state to the server.
// client;{let client = await harpywebSocket;let result = await client;if !result// you can also call describe later to send state whenever needed,// which gives a promise to be sure it makes it to the server.await client;console;};
corresponding server:
// server;harpywebSocket;
emitting events
if you need ad-hoc message passing, you can use the event emitter:
// server// note: using babel is optional, but more fun.;harpywebSocket;
and a corresponding client:
// client;{let client = await harpywebSocket;clientevents;};
communication protocols
So far there is no implementation with fallbacks (using say, socket.io or primus,) so each server/client pair is specific to a single protocol.
socket
Plain Node.js net sockets.
It can be accessed using require('harpy').socket
, or require('harpy/lib/socket')
// server;// all server options are passed to net.createServer// if a `port` is passed, net.listen will be called during construction.var opts = port: 9000 ;var server = harpysocket;// createServer returns the underlying net serverserver;// clientvar promise = harpysocket;promise;
websocket
Websockets are created using the websockets/ws library, or natively on the browser.
It can be accessed using require('harpy').webSocket
, or require('harpy/lib/websocket')
// server;// all server options are passed to the ws.Server constructorvar opts = port: 9000 ;var server = harpywebSocket;// createServer returns the underlying ws serverserver;// clientvar promise = harpywebSocket;promise;
browser support
The WebSocket protocol does not use any polyfills at this time, so it's limited to IE10+. If that's not a problem, you can require('harpy')
with browserify or webpack and use harpy.webSocket.connect
.
client object
The client object is used on both the server- and client-side to send and receive messages.
// Default client structureclient =events: EventEmitterstate: EventEmitter +connected: true// callId stores the id of the previous rpc-call,// this is incremented for every call.callId: 0// describe is a reference to the functions that// can be called from the remote. it is replaced// by calling `client.describe`.describe: ...// @emit is called when the remote triggers an event."@emit": Function// @describe is called when the remote is replacing its description."@describe": Function// the describe function calls @describe on the remote,// to tell it which functions are available on this client.describe: Function// emit calls @emit on the remote, which triggers an event.emit: Function// any other functions that are added using the describe function// on the remote are found on this object as well.
client.state events
Client.state has a few events that can be used to detect changes in the connection.
open
- connected, but no service description has been receieveddescribe
- an updated service description has been receivedconnect
- connected, and a service description has been receivedsend
- a message is ready to be sent to the remotemessage
- a message has been received from the remoteresult:{id}
- a remote procedure call has returned a valuedisconnect
- the transport has disconnect, but might reconnectclose
- the transport is shutting down, and will not reconnect
client.events events
Client.events is only triggered by calling Client.emit(name, args)
, and can have any event names.
creation options
When connecting to a server using socket.connect
or webSocket.connect
,
you can supply options (well, option..) to configure the client.
describe
- state object that is sent to the server when connecting, can be used to pass state needed for initializing the remote service.
messaging protocol
Harpy uses JSON-RPC messages, with single line JSON. It does not support notification requests at this time, all requests must be responded to.
example messages
In order to begin communicating, both client and server must send their description. The client starts this, by calling the "@describe" function.
This tells the server to create an rpc-function called "test", and an extra value to add to the client
object. The object can be arbitrarily nested.. When the server is ready, it responds to the message and sends its own description.
The client then responds to the message, and calls its login function.
After the server is done processing the request, it will respond with its result:
Different error codes are sent based on the JSON-RPC spec. code
and friendlyMessage
are used from any thrown Error objects. If no friendlyMessage is found, "Unhandled error" will be used. Let's try that again..
There we go, everything's spelled right, now we'll get a response:
And that's it!