The "Hello World" Tutorial is a very basic example, based on Lightstreamer, where we push the alternated strings "Hello" and "World", followed by the current timestamp, from the server to the browser.
This project is a Node.js port of the Lightstreamer - "Hello World" Tutorial - Java Adapter, and contains the source code and all the resources needed to install the Node.js Remote Adapters for the "Hello World" Tutorial.
As an example of Clients Using This Adapter, you may refer to the Lightstreamer - "Hello World" Tutorial - HTML Client and view the corresponding Live Demo.
First, please take a look at the previous installment Lightstreamer - "Hello World" Tutorial - HTML Client, which provides some background and the general description of the application. Notice that the front-end will be exactly the same. We created a very simple HTML page that subscribes to the "greetings" item, using the "HELLOWORLD" Adapter. Now, we will replace the "HELLOWORLD" Adapter implementation based on Java with a JavaScript equivalent. On the client side, nothing will change, as server-side Adapters can be transparently switched and changed, as long as they respect the same interfaces. Thanks to this decoupling, provided by Lightstreamer Server, we could even do something different. For example, we could keep the Java Adapter on the server side and use node.js, instead of HTML, on the client side. Or, we could use the Node.js Adapter on the server side and use Java, instead of HMTL or node.js, on the client side. Basically, all the combinations of languages and technologies on the client side and on the server side are supported.
This project shows the use of DataProvider and MetadataProvider classes provided in the Lightstreamer SDK for Node Adapters.
Lightstreamer Server exposes native Java Adapter interfaces. The Node.js interfaces are added through the Lightstreamer Adapter Remoting Infrastructure (ARI). Let's have a look at it.
ARI is simply made up of two Proxy Adapters and a Network Protocol. The two Proxy Adapters implement the Java interfaces and are meant to be plugged into Lightstreamer Kernel, exactly as we did for our original "HELLOWORLD" Java Adapter. There are two Proxy Adapters because one implements the Data Adapter interface and the other implements the Metadata Adapter interface. Our "Hello World" example uses a default Metadata Adapter, so we only need the Proxy Data Adapter.
What does the Proxy Data Adapter do? Basically, it exposes the Data Adapter interface through TCP sockets. In other words, it offers a Network Protocol, which any remote counterpart can implement to behave as a Lightstreamer Data Adapter. This means you can write a remote Data Adapter in C, in PHP, or in COBOL (?!?), provided that you have access to plain TCP sockets.
But - here is some magic - if your remote Data Adapter is based on Node.js, you can forget about direct socket programming, and leverage a ready-made library that exposes a higher level JavaScript interface. So, you will simply have to implement this JavaScript interface.
Okay, let's recap... The Proxy Data Adapter converts from a Java interface to TCP sockets. The Node.js library converts from TCP sockets to a JavaScript interface. Clear enough?
You may find more details about ARI in Adapter Remoting Infrastructure Network Protocol Specification. You may find more details about how to write Data Adapters and Metadata Adapters for Lightstreamer Server in a Node.js environment in Lightstreamer SDK for Node Adapters. The full Node.js Adapter API Reference covered in this tutorial are available at Lightstreamer Node.js Adapter SDK API.
The helloworld.cjs
file containing all the required JavaScript code.
First, we include the modules we need and setup some configuration variables.
var DataProvider = require('lightstreamer-adapter').DataProvider;
var net = require('net');
var HOST = 'localhost';
var PORT = 6663;
Then, we create a stream that will be used by our DataProvider to communicate with the Proxy Data Adapter. We use the standard net module to do so:
var stream = net.createConnection(PORT, HOST);
Finally, we create our DataProvider instance.
var dataProvider = new DataProvider(stream);
At this point, the application is kind of ready-ish. It doesn't do anything but "it works".
Now we want to handle the DataProvider events to listen for subscribe/unsubscribe calls and start generating real-time events.
var greetingsThread;
dataProvider.on('subscribe', function(itemName, response) {
if (itemName === "greetings") {
greetingsThread = setTimeout(generateGreetings,0);
response.success();
}
});
dataProvider.on('unsubscribe', function(itemName, response) {
console.log("Unsubscribed item: " + itemName);
if (itemName === "greetings") {
clearTimeout(greetingsThread);
response.success();
}
});
var c = false;
function generateGreetings() {
c = !c;
dataProvider.update("greetings", false, {
'timestamp': new Date().toLocaleString(),
'message': c ? "Hello" : "World"
});
greetingsThread = setTimeout(generateGreetings,1000+Math.round(Math.random()*2000));
}
When the "greetings" item is subscribed to by the first user, the Adapter receives the subscribe event and starts generating the real-time data. If more users subscribe to the "greetings" item, the subscribe event is not fired anymore. When the last user unsubscribes from this item, the Adapter is notified through the unsubscribe event. In this case, we stop the generating events for that item. If a new user re-subscribes to "greetings", the subscribe event is fired again. As already mentioned in the previous installment, this approach avoids consuming processing power for items no one is currently interested in.
The greetingsThread function is responsible for generating the real-time events. Its code is very simple. We simply call the dataProvider.update method passing in the item name we want to update and a JSON object representing our update containing a message (alternating "Hello" and "World") and the current timestamp. The function then calls itself using setTimeout to wait for a random time between 1 and 3 seconds and generate the next event.
The lightstreamer-adapter
package is compatible with ES modules. For an example, refer to the helloworld.mjs
file.
The helloworld.ts
file demonstrates how to use the lightstreamer-adapter
package in a Typescript module.
To compile the Typescript code to Javascript, follow these steps:
- Install the dependencies listed in
package.json
$ npm install
- Invoke the Typescript compiler
$ npx tsc helloworld.ts
This command will result in a new file named helloworld.js
that can be run using Node.js.
This Adapter Set is configured and will be referenced by the clients as NODE_HELLOWORLD
.
For this demo, we configure just the Data Adapter as a Proxy Data Adapter, while instead, as Metadata Adapter, we use the LiteralBasedProvider, a simple full implementation of a Metadata Adapter, already provided by Lightstreamer server.
As Proxy Data Adapter, you may configure also the robust versions. The Robust Proxy Data Adapter has some recovery capabilities and avoid to terminate the Lightstreamer Server process, so it can handle the case in which a Remote Data Adapter is missing or fails, by suspending the data flow and trying to connect to a new Remote Data Adapter instance. Full details on the recovery behavior of the Robust Data Adapter are available as inline comments within the provided template.
The adapters.xml
file for this demo should look like:
<?xml version="1.0"?>
<adapters_conf id="NODE_HELLOWORLD">
<metadata_provider>
<adapter_class>com.lightstreamer.adapters.metadata.LiteralBasedProvider</adapter_class>
</metadata_provider>
<data_provider>
<adapter_class>PROXY_FOR_REMOTE_ADAPTER</adapter_class>
<param name="request_reply_port">6663</param>
</data_provider>
</adapters_conf>
NOTE: not all configuration options of a Proxy Adapter are exposed by the file suggested above.
You can easily expand your configurations using the generic template
for basic and robust Proxy Adapters as a reference.
If you want to install a version of this demo in your local Lightstreamer Server, follow these steps:
- Download Lightstreamer Server (Lightstreamer Server comes with a free non-expiring demo license for 20 connected users) from Lightstreamer Download page, and install it, as explained in the
GETTING_STARTED.TXT
file in the installation home directory. - Get the
deploy.zip
file of the "latest" release and unzip it, obtaining thedeployment
folder. - Plug the Proxy Data Adapter into the Server: go to the
deployment/Deployment_LS
folder and copy theNodeHelloWorld
directory and all of its files to theadapters
folder of your Lightstreamer Server installation. - Alternatively, you may plug the robust versions of the Proxy Data Adapter: go to the
deployment/Deployment_LS(robust)
folder and copy theNodeHelloWorld
directory and all of its files into theadapters
folder. - Install the lightstreamer-adapter module.
- Create a directory where to deploy the Node.js Remote Adapter and let call it
Deployment_Node_Remote_Adapter
. - Go to the
Deployment_Node_Remote_Adapter
folder and launch the command:
> npm install lightstreamer-adapter
- Download the
helloworld.cjs
file from this project and copy it into theDeployment_Node_Remote_Adapter
folder.
- Create a directory where to deploy the Node.js Remote Adapter and let call it
- Launch Lightstreamer Server. The Server startup will complete only after a successful connection between the Proxy Data Adapter and the Remote Data Adapter.
- Launch the Node.js Remote Adapter: go to the
Deployment_Node_Remote_Adapter
folder and launch:
> node helloworld.cjs
- Test the Adapter, launching the "Hello World" Tutorial - HTML Client listed in Clients Using This Adapter.
- To make the "Hello World" Tutorial - HTML Client front-end pages get data from the newly installed Adapter Set, you need to modify the front-end pages and set the required Adapter Set name to NODE_HELLOWORLD, when creating the LightstreamerClient instance. So edit the
index.htm
page of the Hello World front-end, deployed underLightstreamer/pages/HelloWorld
, and replace:
var client = new LightstreamerClient(null," HELLOWORLD");
with:
var client = new LightstreamerClient(null,"NODE_HELLOWORLD");;
- Open a browser window and go to: http://localhost:8080/HelloWorld/
- To make the "Hello World" Tutorial - HTML Client front-end pages get data from the newly installed Adapter Set, you need to modify the front-end pages and set the required Adapter Set name to NODE_HELLOWORLD, when creating the LightstreamerClient instance. So edit the
- Complete list of "Hello World" Adapter implementations with other technologies
- Lightstreamer - Reusable Metadata Adapters - Java Adapter
- Compatible with Lightstreamer SDK for Node.js Adapters version 1.7 or newer and Lightstreamer Server version 7.4 or newer.
- For a version of this example compatible with Lightstreamer Server version since 6.0, please refer to this tag.
- For a version of this example compatible with Lightstreamer SDK for Node.js Adapters version 1.3 to 1.6, please refer to this tag.
- For a version of this example compatible with Lightstreamer SDK for Node.js Adapters version 1.0, please refer to this tag.
Please post to our support forums any feedback or question you might have. Thanks!