Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Asyngular is a framework for writing scalable real-time applications which leverage the latest async/await features of JavaScript (works well with async generators). It is a fork of SocketCluster; a (5+ years) battle-tested framework used in production by hundreds of companies. See this article for a list of improvements which Asyngular introduces over SocketCluster.
The Asyngular GitHub repo is here: https://github.com/SocketCluster/asyngular
Requirements
- Node.js v10 (can work with older versions but you won’t be able to use the for-await-of loop to consume streams)
Optional dependency (for containerization):
- docker CLI
Installing
The easiest way to get started with Asyngular is to install the CLI toolkit from npm:
// Or with sudonpm install -g asyngular
then run this in your console/terminal:
asyngular create myapp
Running the server
Once it’s ready, go to your new myapp/ directory and launch with:
node server
You can interact with your app by opening http://localhost:8000/ in your browser.
If you have docker installed, you can alternatively run your Asyngular app inside a container on your local machine using the following shortcut command (run from inside your myapp/ directory):
asyngular run
Stop and remove container with:
asyngular stop
Use asyngular --help for a list of all docker shortcut commands.
[Server] Listening for inbound socket connections
Inside server.js, find the for-await-of loop which is handling inbound connections. It should look like this:
[Server] Listening for inbound RPCs and messages
You can add nested for-await-of loops to handle different kinds of socket messages/RPCs within this main connection loop. For example:
!! Note that you can also register socket.procedure(procedureName) and socket.receiver(receiverName) handlers on a client socket using the same syntax.
[Client] Connecting to the server
Note that you can pass an optional object to the asyngularClient.create function to modify socket options. This function supports the same options as the create function on the socketcluster-client. See https://socketcluster.io/#!/docs/api-socketcluster-client for more details.
[Client] Invoking RPCs
!! Note that you should always add a try-catch block around the socket.invoke call to capture any async errors:
!! Note that you can also invoke procedures which are registered on the client socket from the server socket using the same syntax.
[Client] transmitting messages
!! Note that you can also transmit to receivers which are registered on the client socket from the server socket using the same syntax. Transmit can never fail, so you don’t need a try-catch block.
[Client] Subscribing to a channel and watching for messages
[Client] Publishing to a channel
!! Note that you can also publish from an AGChannel object; in this case, you omit the first parameter. For example:
let fooChannel = socket.channel('foo');fooChannel.transmitPublish('This is some data');
[Server] Publishing to a channel
[Server] Registering middleware functions
Asyngular supports 4 different middleware lines which allow you to block, delay or preprocess specific actions. Middleware functions in Asyngular work differently from those in SocketCluster. In Asyngular, a middleware function can handle multiple different types of actions (represented by an AGAction instance which has a type property).
The following middleware lines and actions are supported:
- AGServer.MIDDLEWARE_HANDSHAKE: The for-await-of loop iterates whenever a socket handshake occurs. The action.type property can be either AGAction.HANDSHAKE_WS or AGAction.HANDSHAKE_AG.
- AGServer.MIDDLEWARE_INBOUND_RAW: The for-await-of loop iterates whenever an inbound message (I.e. from client -> server) is received by the server. This includes all raw messages and operations; including those which are not recognized by Asyngular. The action.type property will always be AGAction.MESSAGE.
- AGServer.MIDDLEWARE_INBOUND: The for-await-of loop iterates whenever an inbound operation (I.e. a recognized operation from client -> server) occurs. The action.type property can be AGAction.TRANSMIT, AGAction.INVOKE, AGAction.SUBSCRIBE, AGAction.PUBLISH_IN, AGAction.PUBLISH_OUT or AGAction.AUTHENTICATE.
- AGServer.MIDDLEWARE_OUTBOUND: The for-await-of loop iterates whenever an outbound operations (I.e. server -> client) occurs. The action.type property will always be AGAction.PUBLISH_OUT.
This is how to setup a middleware (this example shows the MIDDLEWARE_INBOUND middleware handling TRANSMIT and INVOKE actions):
!! Note that in Asyngular, you can only have one middleware function for each middleware line.
Each action object (AGAction) which is streamed through the middleware has different properties depending on its type property. These are the properties supported by different action types:
- AGAction.HANDSHAKE_WS: type and request properties.
- AGAction.HANDSHAKE_AG: type, request and socket properties.
- AGAction.MESSAGE: type, socket and data properties.
- AGAction.TRANSMIT: type, socket, receiver and data properties.
- AGAction.INVOKE: type, socket, procedure and data properties.
- AGAction.SUBSCRIBE: type, socket, channel and data properties.
- AGAction.PUBLISH_IN: type, socket, channel and data properties.
- AGAction.PUBLISH_OUT: type, socket, channel and data properties.
- AGAction.AUTHENTICATE: type, socket, signedAuthToken and authToken properties.
^ In all of the above cases, type is a string, channel is a string, request is a Node.js http.IncomingMessage object, socket is an AGServerSocket object, receiver is a string, procedure is a string, signedAuthToken is a string, authToken is an object (or null) and data can be of any type (depending on what is provided by the client).
Supporting documentation
- https://github.com/SocketCluster/asyngular
- https://github.com/SocketCluster/asyngular-server
- https://github.com/SocketCluster/asyngular-client
- https://socketcluster.io/
Getting started with Asyngular was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.