“Hello World” with Lightstreamer
(Originally published on cometdaily.com)
Let’s see how to build a “Hello World” application with
Lightstreamer. The client will be based on HTML, while the server Data Adapter will be based on Java.
We will start from scratch and with zero knowledge of the
framework. I will introduce some terms and concepts while explaining the
code.
What do we want our application to do?
Let’s keep the application very basic. We want to push the alternated strings
“Hello” and “World”, followed by the current timestamp, from the server to the
browser. Yes, a very exciting application…
What data model should we use?
In the Lightstreamer framework, you subscribe to items. You
will find different terms for this concept in other frameworks. For example, in
Cometd you subscribe to channels. An item
is made up of a number of fields whose values change over time. Here are some
examples of possible items:
- An item in Lightstreamer could represent an item on eBay,
say, a pair of “Nike Air Jordan” shoes. The item name would
be “NIKE-AIR-JORDAN-XX3-XXIII-23-PREMIER-Limited-sz-10”. Some
fields would be: current_bid, total_bids,
and high_bidder. (By the way, I see that the current bid is $1,300.00
right now; not so bad…). When a field changes, the new value is pushed to the
browser and displayed in real time.
- An item could represent a weather probe. The item name
would be, for example, “Mt_Everest_Probe.1” (this probe
was left by MIT after the 1998 Everest Expedition). Some fields would be:
temperature, barometric_pressure, and light_level.
- In the most classical Comet application, finance market data
dissemination, an item often represents a stock quote. The item name
would be, for example, “TIBX.O” (TIBCO Software Inc. on Nasdaq). Some fields
would be: TRDPRC_1, TRDTIM_1, BID, and
ASK.
That said, how can we represent our very complex Hello World
messages? Of course through an item… The item name will be
“greetings”. It will have two fields:
message and timestamp.
Let’s get started
First, download
and install Lightstreamer. After you see the Stock-List Demo
running, you will be sure that the Server is ready to host our application.
Now we need to develop two components: the front-end (on the client side),
and the Data Adapter (on the server side).
Creating the front-end
The front-end of this oh-so-cool application will be a simple HTML page that
displays the real-time data pushed by the Server. Here is the result:

First, we should include a couple of Lightstreamer libraries:
<script language='JavaScript' src = 'LS/lscommons.js'></script>
<script language='JavaScript' src = 'LS/lspushpage.js'></script>
Then, we can create two div elements that will host the pushed fields:
<div source="lightstreamer" table="hellotable" item="greetings"
field="message">loading...</div>
<div source="lightstreamer" table="hellotable" item="greetings"
field="timestamp">loading...</div>
The source=”lightstreamer” property binds a div element to Lightstreamer. The
item and field properties identify the data to be subscribed to and displayed.
The initial value displayed on the page will be “loading…”, which will be
replaced by the real-time data after the subscription has been done.
Finally, let’s add some JavaScript code to tie things together:
<script>
var page = new PushPage();
page.onEngineCreation = function(engine) {
engine.connection.setAdapterName("HELLOWORLD");
engine.changeStatus("STREAMING");
}
page.bind();
page.createEngine("HelloWorldApp", "LS", "SHARE_SESSION");
var pushtable = new OverwriteTable(null, null, "MERGE");
page.addTable(pushtable, "hellotable");
</script>
We call any page in the Web application that will receive real-time data a
Push-Page. Every Push-Page should contain a PushPage
object. One of the Push-Pages must be a Master
Push-Page, meaning that it must contain the
LightstreamerEngine, a JavaScript object that abstracts all the
Comet functionalities of Lightstreamer. The code above creates a PushPage object
and binds it to the current page. Then it creates the LightstreamerEngine,
naming it “HelloWorldApp”. (This is a name that identifies the application; more
instances of the same application can automatically share the same engine, and
therefore the same connections, thanks to the “SHARE_SESSION” flag). The
onEngineCreation callback is invoked on the Master Push-Page after the engine
has actually been created. This callback is the place to configure the server
details (not necessary here, because we will connect to localhost) and to start
the Comet session by calling changeStatus(”STREAMING”).
The
OverwriteTable object is used to encapsulate the subscription
details and the visual binding to the HTML widgets. When calling addTable, we
specify that this OverwriteTable should be bound to the HTML elements that we
tagged with the property table=”hellotable”.
The full source code of this page is shown below (and
is included in this archive):

Creating the Data Adapter
Good, we have a front-end. Now we need to create the server-side code that
will pass the data to the Lightstreamer Server, which in turn will pass it to
the front-end. This is done by writing a Data Adapter, a
plug-in module that injects data into the Server. Let’s choose Java to write our
Data Adapter (the other options would be to use .NET or to work at the socket
level).
First, we need to implement the SmartDataProvider interface:
public class HelloWorldDataAdapter implements SmartDataProvider {
We will be passed a reference to a listener that we will use to inject
events:
private ItemEventListener listener;
public void setListener(ItemEventListener listener) {
this.listener = listener;
}
Then we should be ready to accept subscription requests (remember that
Lightstreamer is currently based on asymmetric
Comet):
public void subscribe(String itemName, Object itemHandle,
boolean needsIterator)
throws SubscriptionException, FailureException {
if (itemName.equals("greetings")) {
gt = new GreetingsThread(itemHandle);
gt.start();
}
}
When the “greetings” item is subscribed to by the first user, our Adapter
receives that method call and starts a thread that will generate the real-time
data. If more users subscribe to the “greetings” item, the subscribe method is
not called any more. When the last user unsubscribes from this item, our Adapter
is notified through the unsubscribe call:
public void unsubscribe(String itemName)
throws SubscriptionException, FailureException {
if (itemName.equals("greetings") && gt != null) {
gt.go = false;
}
}
We can then stop publishing data for that item. If a new user re-subscribes
to “greetings”, the subscribe method is called again. This approach avoids
consuming processing power for items nobody is currently interested in.
Now, let’s see what the GreetingsThread does. Its run method
is pretty straightforward:
public void run() {
int c = 0;
Random rand = new Random();
while(go) {
Map data = new HashMap();
data.put("message", c % 2 == 0 ? "Hello" : "World");
data.put("timestamp", new Date().toString());
listener.smartUpdate(itemHandle, data, false);
c++;
try {
Thread.sleep(1000 + rand.nextInt(2000));
} catch (InterruptedException e) {
}
}
}
We create a HashMap containing the message (alternating “Hello” and “World”)
and the current timestamp. Then we inject the HashMap into the Lightstreamer
Server through the listener (and the itemHandle we were passed at subscription
time). We do a random pause between 1 and 3 seconds, and we are ready to
generate a new event.
The full source code of this Data Adapter is shown below (and
is included in this archive):

Let’s deploy the Adapter
We should now compile the Data Adapter and plug it into the Lightstreamer
Server. To compile it, we need to include the Adapter
interface in the Java compiler classpath. We can find this interface in
the ls-adapter-interface.jar file located in
“Lightstreamer/DOCS-SDKs/sdk_adapter_java/lib” within your installation. If
compiling succeeds, you will get two classes:
- HelloWorldDataAdapter$GreetingsThread.class
-
HelloWorldDataAdapter.class
To deploy a Data Adapter, we need to create a folder directly under
“Lightstreamer/adapters”. Let’s call it “HelloWorld”. Create a “classes” folder inside
“HelloWorld” and put the two .class files in it.
The final step is to create a deployment descriptor for this
Adapter. This file should be called “adapters.xml” and put in the “HelloWorld”
folder. Its content is very simple:
<?xml version="1.0"?>
<adapters_conf id="HELLOWORLD">
<metadata_provider>
<adapter_class>
com.lightstreamer.adapters.metadata.LiteralBasedProvider
</adapter_class>
</metadata_provider>
<data_provider>
<adapter_class>
HelloWorldDataAdapter
</adapter_class>
</data_provider>
</adapters_conf>
We assign an ID to our Adapter:
“HELLOWORLD”. This is the same that we used in the
setAdapterName method of the client. Then, we define a default Metadata Adapter
(a Metadata Adapter is responsible for managing authentication, authorization,
and quality of service; we don’t need any custom behavior for our application).
And we define the main class of our brand new Data Adapter.
Let’s deploy the client
We only need to deploy our Web page and we are done. To make
this fast, we decide to use the Lightstreamer Server as a Web server too,
meaning both the static resources and the real-time data will be delivered by
the Lightstreamer Server. But the typical production architecture has an
external Web server (whatever it is) in addition to the Lightstreamer Server.
Everything is downloaded from the Web server except for the real-time data,
which comes from the Lightstreamer Server. This separation improves both
flexibility (you are free to use whatever Web/application server you want) and
performance (you can isolate the power-demanding Comet connections to a separate
box, without impacting your existing Web infrastructure).
So, let’s create a “HelloWorld” folder under the “Lightstreamer/pages”
folder. We name the HTML file created above as “index.htm” and put it in the
“HelloWorld” folder. Finally, we have to deploy the JS libraries used by our
page. Let’s create an “LS” folder under “HelloWorld” and copy to it all the
files located in “/Lightstreamer/DOCS-SDKs/sdk_client_html/lib”.
Ready to go
Let’s start our Lightstreamer Server, then open a browser window and go to:
http://localhost:8080/HelloWorld/
Is it working? Hope so…
Final notes
This example was really very basic and exploited only a minor portion of the
features offered by the Lightstreamer API. To delve a bit more into the API used
above (JavaScript and Java), you can take a look at the online API
reference:
- JavaScript doc of
the Web Client API
- Java doc
of the Adapter API
Let’s see how to build a “Hello World” application with Lightstreamer. The client will be based on HTML, while the server Data Adapter will be based on Java. We will start from scratch and with zero knowledge of the framework. I will introduce some terms and concepts while explaining the code.
What do we want our application to do?
Let’s keep the application very basic. We want to push the alternated strings “Hello” and “World”, followed by the current timestamp, from the server to the browser. Yes, a very exciting application…
What data model should we use?
In the Lightstreamer framework, you subscribe to items. You will find different terms for this concept in other frameworks. For example, in Cometd you subscribe to channels. An item is made up of a number of fields whose values change over time. Here are some examples of possible items:
- An item in Lightstreamer could represent an item on eBay, say, a pair of “Nike Air Jordan” shoes. The item name would be “NIKE-AIR-JORDAN-XX3-XXIII-23-PREMIER-Limited-sz-10”. Some fields would be: current_bid, total_bids, and high_bidder. (By the way, I see that the current bid is $1,300.00 right now; not so bad…). When a field changes, the new value is pushed to the browser and displayed in real time.
- An item could represent a weather probe. The item name would be, for example, “Mt_Everest_Probe.1” (this probe was left by MIT after the 1998 Everest Expedition). Some fields would be: temperature, barometric_pressure, and light_level.
- In the most classical Comet application, finance market data dissemination, an item often represents a stock quote. The item name would be, for example, “TIBX.O” (TIBCO Software Inc. on Nasdaq). Some fields would be: TRDPRC_1, TRDTIM_1, BID, and ASK.
That said, how can we represent our very complex Hello World messages? Of course through an item… The item name will be “greetings”. It will have two fields: message and timestamp.
Let’s get started
First, download and install Lightstreamer. After you see the Stock-List Demo running, you will be sure that the Server is ready to host our application.
Now we need to develop two components: the front-end (on the client side), and the Data Adapter (on the server side).
Creating the front-end
The front-end of this oh-so-cool application will be a simple HTML page that displays the real-time data pushed by the Server. Here is the result:

First, we should include a couple of Lightstreamer libraries:
<script language='JavaScript' src = 'LS/lscommons.js'></script>
<script language='JavaScript' src = 'LS/lspushpage.js'></script>
Then, we can create two div elements that will host the pushed fields:
<div source="lightstreamer" table="hellotable" item="greetings"
field="message">loading...</div>
<div source="lightstreamer" table="hellotable" item="greetings"
field="timestamp">loading...</div>
The source=”lightstreamer” property binds a div element to Lightstreamer. The item and field properties identify the data to be subscribed to and displayed. The initial value displayed on the page will be “loading…”, which will be replaced by the real-time data after the subscription has been done.
Finally, let’s add some JavaScript code to tie things together:
<script>
var page = new PushPage();
page.onEngineCreation = function(engine) {
engine.connection.setAdapterName("HELLOWORLD");
engine.changeStatus("STREAMING");
}
page.bind();
page.createEngine("HelloWorldApp", "LS", "SHARE_SESSION");
var pushtable = new OverwriteTable(null, null, "MERGE");
page.addTable(pushtable, "hellotable");
</script>
We call any page in the Web application that will receive real-time data a
Push-Page. Every Push-Page should contain a PushPage
object. One of the Push-Pages must be a Master
Push-Page, meaning that it must contain the
LightstreamerEngine, a JavaScript object that abstracts all the
Comet functionalities of Lightstreamer. The code above creates a PushPage object
and binds it to the current page. Then it creates the LightstreamerEngine,
naming it “HelloWorldApp”. (This is a name that identifies the application; more
instances of the same application can automatically share the same engine, and
therefore the same connections, thanks to the “SHARE_SESSION” flag). The
onEngineCreation callback is invoked on the Master Push-Page after the engine
has actually been created. This callback is the place to configure the server
details (not necessary here, because we will connect to localhost) and to start
the Comet session by calling changeStatus(”STREAMING”).
The
OverwriteTable object is used to encapsulate the subscription
details and the visual binding to the HTML widgets. When calling addTable, we
specify that this OverwriteTable should be bound to the HTML elements that we
tagged with the property table=”hellotable”.
The full source code of this page is shown below (and is included in this archive):

Creating the Data Adapter
Good, we have a front-end. Now we need to create the server-side code that will pass the data to the Lightstreamer Server, which in turn will pass it to the front-end. This is done by writing a Data Adapter, a plug-in module that injects data into the Server. Let’s choose Java to write our Data Adapter (the other options would be to use .NET or to work at the socket level).
First, we need to implement the SmartDataProvider interface:
public class HelloWorldDataAdapter implements SmartDataProvider {
We will be passed a reference to a listener that we will use to inject
events:
private ItemEventListener listener;
public void setListener(ItemEventListener listener) {
this.listener = listener;
}
Then we should be ready to accept subscription requests (remember that
Lightstreamer is currently based on asymmetric
Comet):
public void subscribe(String itemName, Object itemHandle,
boolean needsIterator)
throws SubscriptionException, FailureException {
if (itemName.equals("greetings")) {
gt = new GreetingsThread(itemHandle);
gt.start();
}
}
When the “greetings” item is subscribed to by the first user, our Adapter receives that method call and starts a thread that will generate the real-time data. If more users subscribe to the “greetings” item, the subscribe method is not called any more. When the last user unsubscribes from this item, our Adapter is notified through the unsubscribe call:
public void unsubscribe(String itemName)
throws SubscriptionException, FailureException {
if (itemName.equals("greetings") && gt != null) {
gt.go = false;
}
}
We can then stop publishing data for that item. If a new user re-subscribes to “greetings”, the subscribe method is called again. This approach avoids consuming processing power for items nobody is currently interested in.
Now, let’s see what the GreetingsThread does. Its run method is pretty straightforward:
public void run() {
int c = 0;
Random rand = new Random();
while(go) {
Map data = new HashMap();
data.put("message", c % 2 == 0 ? "Hello" : "World");
data.put("timestamp", new Date().toString());
listener.smartUpdate(itemHandle, data, false);
c++;
try {
Thread.sleep(1000 + rand.nextInt(2000));
} catch (InterruptedException e) {
}
}
}
We create a HashMap containing the message (alternating “Hello” and “World”) and the current timestamp. Then we inject the HashMap into the Lightstreamer Server through the listener (and the itemHandle we were passed at subscription time). We do a random pause between 1 and 3 seconds, and we are ready to generate a new event.
The full source code of this Data Adapter is shown below (and is included in this archive):

Let’s deploy the Adapter
We should now compile the Data Adapter and plug it into the Lightstreamer Server. To compile it, we need to include the Adapter interface in the Java compiler classpath. We can find this interface in the ls-adapter-interface.jar file located in “Lightstreamer/DOCS-SDKs/sdk_adapter_java/lib” within your installation. If compiling succeeds, you will get two classes:
- HelloWorldDataAdapter$GreetingsThread.class
-
HelloWorldDataAdapter.class
To deploy a Data Adapter, we need to create a folder directly under “Lightstreamer/adapters”. Let’s call it “HelloWorld”. Create a “classes” folder inside “HelloWorld” and put the two .class files in it.
The final step is to create a deployment descriptor for this Adapter. This file should be called “adapters.xml” and put in the “HelloWorld” folder. Its content is very simple:
<?xml version="1.0"?>
<adapters_conf id="HELLOWORLD">
<metadata_provider>
<adapter_class>
com.lightstreamer.adapters.metadata.LiteralBasedProvider
</adapter_class>
</metadata_provider>
<data_provider>
<adapter_class>
HelloWorldDataAdapter
</adapter_class>
</data_provider>
</adapters_conf>
We assign an ID to our Adapter: “HELLOWORLD”. This is the same that we used in the setAdapterName method of the client. Then, we define a default Metadata Adapter (a Metadata Adapter is responsible for managing authentication, authorization, and quality of service; we don’t need any custom behavior for our application). And we define the main class of our brand new Data Adapter.
Let’s deploy the client
We only need to deploy our Web page and we are done. To make this fast, we decide to use the Lightstreamer Server as a Web server too, meaning both the static resources and the real-time data will be delivered by the Lightstreamer Server. But the typical production architecture has an external Web server (whatever it is) in addition to the Lightstreamer Server. Everything is downloaded from the Web server except for the real-time data, which comes from the Lightstreamer Server. This separation improves both flexibility (you are free to use whatever Web/application server you want) and performance (you can isolate the power-demanding Comet connections to a separate box, without impacting your existing Web infrastructure).
So, let’s create a “HelloWorld” folder under the “Lightstreamer/pages” folder. We name the HTML file created above as “index.htm” and put it in the “HelloWorld” folder. Finally, we have to deploy the JS libraries used by our page. Let’s create an “LS” folder under “HelloWorld” and copy to it all the files located in “/Lightstreamer/DOCS-SDKs/sdk_client_html/lib”.
Ready to go
Let’s start our Lightstreamer Server, then open a browser window and go to: http://localhost:8080/HelloWorld/
Is it working? Hope so…
Final notes
This example was really very basic and exploited only a minor portion of the features offered by the Lightstreamer API. To delve a bit more into the API used above (JavaScript and Java), you can take a look at the online API reference:
- JavaScript doc of
the Web Client API
- Java doc
of the Adapter API