SitePen Support

“Hello World” with Lightstreamer

by Alessandro AlinoneFebruary 12th, 2008

After a couple of abstract installments, I would like to delve into some more practical details. Let’s see how to build a “Hello World” Comet application with Lightstreamer (and I really mean “Hello World”… not a chat application, which is often considered the “Hello World” of Comet). 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

This application will be based on Lightstreamer Server v.3.4 and Web Client v.4.2, which are the current production versions. First, download and install Lightstreamer Moderato. 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:

Hello World with Lightstreamer - Firefox screenshot

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):

Hello World with Lightstreamer - Page source

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):

Hello World with Lightstreamer - Adapter source

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 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_web/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:

- JSdoc of the Web Client API
- Javadoc of the Adapter API

We used the Moderato edition of Lightstreamer. Its main limitation, with respect to the commercial editions, is that it only allows 1 update/sec for each subscribed item. There are no limits on how many items you can subscribe to at the same time, but if you want to push higher-frequency events for the same item (like our “greetings” item) you will see that no more that 1 event/sec is delivered to the client. If you need to experiment with higher frequencies, you can use an evaluation license of Lightstreamer Presto or Vivace.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]
Orbited

39 Responses to ““Hello World” with Lightstreamer”

  1. Steven Roussey Says:

    Funny, everyone says chat is the hello world of comet, yet there is not an article on here going through the motions as you have nicely done in this article…

  2. DylanSchiemann Says:

    @Steven: This post is the first of hopefully many more that will do just that. Alessandro did a great job here, as always, explaining how to use Lightstreamer.

  3. Rams Says:

    This is a good article for java users. It is more appreciated if we have like this article for programming the adapter using .net because I am googling from so many days to find this kind of article in .net but till now not succeded……

  4. Comet Daily » Blog Archive » Developing for Comet Says:

    [...] Hub we developed a client written using TIBCO GI to which we published data using both DWR and Lightstreamer without any changes to the GI code. We just plugged a different data source into the [...]

  5. Comet Daily » Blog Archive » “Hello World” for .NET with Lightstreamer Says:

    [...] publishing the article “Hello World” with Lightstreamer, I received many requests to release a version of that tutorial for .NET developers. Therefore, in [...]

  6. Alessandro Alinone Says:

    @Rams: an article for .NET developer is now available. Check out http://cometdaily.com/2008/04/14/hello-world-for-net-with-lightstreamer/

  7. wirelessdreamer Says:

    could you post a socket example, that would be universal to any backend programming language, and help make lightstreamer more accessable to non java people.

  8. Alessandro Alinone Says:

    @wirelessdreamer: Good suggestion. I will work on a socket example and publish here as soon as possible.

  9. Peter Wilkinson Says:

    I tried doing this, only I want to run the page making the requests from a different server to the lightstream server.

    I’ve got lightstreamer on port 9090 and jetty server pages on 8080 on localhost.

    I get a whole bunch of permission denied errors instead of the page updating.

    Any ideas?

  10. CK Says:

    I’m a bit unclear on the master push page. To which js window object does the master push page belong? What happens if that window is unloaded? Is a new master selected from the remaining push pages?

  11. Alessandro Alinone Says:

    @Peter: To deploy the pages on a different server, some configuration should be done. Please follow the instructions in the “\Lightstreamer\DOCS-SDKs\sdk_client_web\examples\StockListDemo\README.TXT” file, available within any Lightsteramer Server v.3.4.x distributions. This explains how to deploy the Stock List Demo on an external Web server. You can follow a similar process for the Hello World example.

  12. Alessandro Alinone Says:

    @CK: The Master Push Page is the page that creates the Lightstreamer Engine first. If such page is unloaded, Lightstreamer automatically elects a new master among the other Push Pages and the engine migrates accordingly. For an example and further information please see:
    - a YouTube video at http://lightstreamer.blogspot.com/2008/06/lightstreamer-on-firefox-3.html
    - the comments to http://cometdaily.com/2008/04/24/firefox-30b5-massive-comet-scalability/

  13. Comet Daily » Blog Archive » “Hello World” for Sockets with Lightstreamer Says:

    [...] “Hello World” with Lightstreamer: An introduction to Lightstreamer’s data model, Web Client API, Java Data Adapters, and Server deployment, through the development of a very basic “Hello World” application. [...]

  14. Alessandro Alinone Says:

    @wirelessdreamer: A socket example is now available. You can find it at http://cometdaily.com/2008/07/29/hello-world-for-sockets-with-lightstreamer/

  15. Madhusudan Says:

    I did follow all the steps mentioned in your article. The Lightstreamer server is up and says connected to the dotnet application too, but i do not see any update on the browser - the div tags sho ‘loading…’. Help please!
    Regards,
    Madhu

  16. Madhusudan Says:

    I am sorry i posted my query in the wrong article. I mean I was trying the dotnet example.
    Thanks

  17. Luigi Ipsa Says:

    Hi, i have a problem with this example.
    I have download example code and i try to helloword but from brower i recived popup error:
    Error 2
    Requested Adapter Set not available
    on server log:
    Refused request: Requested Adapter Set, HELLOWORLD, not found from 127.0.0.1:2865
    what is the problem?
    Thanks.

  18. WK Says:

    I also get the Requested Adapter Set not available error. I cannot see why as I have followed everything as suggested.

  19. bryan Says:

    does this site have a glossary? Im new to some terms :)

  20. Shailesh Says:

    i hv got the same problem which Luigi Ipsa had, i.e when i try to runt the index page, I get
    Error 2
    Requested Adapter Set not available
    on server log:
    Refused request: Requested Adapter Set, HELLOWORLD, not found from 127.0.0.1:2865

    Alessandro PLEASE PLEASE HELP!!!!!!

  21. Alessandro Alinone Says:

    Guys, the error message you received means that the Server cannot find any adapter set named “HELLOWORLD”.

    Make sure you use id=”HELLOWORLD” in the adapters.xml file that you have to put in the “Lightstreamer/adapters/HelloWorld” folder. By the way, bear in mind thay the correct directory tree is “Lightstreamer/adapters/HelloWorld” and not “Lightstreamer/adapters/Demo/HelloWorld”.

  22. Salvador Says:

    Hello Alessandro,

    I have the same error equested Adapter Set not available error. I did what you said but I am still having that problem. Do you know how can I sort it out please ?. Appreciate your help.

    Best regards and cheers,

    SAlvador

  23. Alessandro Alinone Says:

    Salvador, for the benefit of the other readers, I report this excerpt from the message you sent me directly: “I have checked word by word your article and I started from the very begining and now is working.”

  24. David Vannucci Says:

    When getting the Requested Adapter Set not available make sure you have placed the .class files in the directory adapters/HelloWorld/classes
    If you have not done so you WILL get this message

  25. Narendra Says:

    Please do a restart of server after following the steps as said by Alessandro.

  26. Comet Daily » Blog Archive » Concrete Comet Examples Says:

    [...] considered the “Hello World” of Comet (even if in the past I preferred to publish an actual “Hello World” application…). One of the first players to propose a full-fledged messenger application based on the [...]

  27. Amoroso Gombe Says:

    Yes, thank you Alessandro, clear, relevant, complete and concise explanation, not often you get that in the IT world. Much appreciated.

  28. Ankit Malik Says:

    hi
    i followed all the steps and trying to deploy the page on a webserver and not on the lightstreamer server..
    The Lightstreamer server is up and i mable to view the demo pages. but with the hello world program i do not see any update on the browser - the div tags shows ‘loading…’.

    if somebody faced this issue and knows how to rectify this … help me to debug this

  29. Alessandro Alinone Says:

    @Ankit: To deploy the page on a web server, please follow the steps explained in the “HOW_TO_DEPLOY_ON_YOUR_WEB_SERVER.TXT” file available in the “\pages\demos” folder of your Lightstreamer installation.

  30. Amoroso Says:

    Hi guys, we think we have found the problem for the error ‘requested adapter set not available’
    We’ve noticed something pretty strange, when we compile the basic helloworld exaample, the adapter classes are placed in the path outside(!) the classes folder, whereas compiling the access database bound code, the adapter classes are place inside the folder as expected.
    Of course this is not a problem in and of itself, the issue is, that whatever path references that are being used to direct the placement of the compiled adapter classes, if the same references are being used to instruct lightstreamer where to find the adapters at run time, they contain an error and lightstreamer therefore fails to initialise because it cannot find them. Alessandro you can duplicate our experiment and see if you can find the error with the path references and perhaps post a new archive with the fix?

  31. Ryan Says:

    I’m confused by the architecture. If I build the adapter in PHP (so sockets), when is this PHP script being executed? Does it need to be called via a web server from the front end HTML page? How often is it being called?

  32. Comet Daily » Blog Archive » “Hello World” for Flex AMF with Lightstreamer Says:

    [...] this tutorial, I’m assuming you have already read the Basic Hello World example, or that you are already familiar with Lightstreamer [...]

  33. Naga Kiran Says:

    ‘requested adapter set not available’.
    Restarting the web server resolved this error.
    Looks like web server needs to be restarted after adding an adapter.

  34. Aminov Says:

    ‘requested adapter set not available’.
    Restsrting the web server resolved this error.
    Looks like web server needs to be restarted after adding an adaptef.;

  35. Vin Yoong Says:

    Hey guys,
    This is a pretty informative tutorial for someone just starting out with lightstreamer. I might have missed some thing out here but, here’s my million dollar question:

    Since the data adapter is sitting on the lightstreamer server, how does an App Server communicate with this data adapter to push data to client?

    So far i see the interfacing between the lightstreamer server to web clients, but i don’t really see the interfacing between an Application Server located at backend (this is where your database is located and essential where ur actual data will come from) with the lightstreamer server.

    Any clues anyone?

  36. Alessandro Alinone Says:

    @Vin: This is exactly the role of the Data Adapter: communicating with the App Server (or data feed in general). You have total freedom in the coding of the Data Adapter, so that you can choose the communication means that makes most sense in your specific scenario.
    For example, some data feeds offer their own integration APIs, which you will use inside your Data Adapters. In other cases you will use some messaging technology (e.g. JMS) or you will connect to a DB, etc.

  37. WG Says:

    i think this product should improve the communication between the Web Applicaiton and DataAdapter . If not,we can`t push the data from web Application to MetaDataAdapter.It`s not good for this.It should have the interface.Yes,that`s right.ha

  38. za Says:

    Thanks Alessandro! I followed your tutorial, and it works. I didn’t re-write the source code, I copied your source code.

    Once I got failed because I thought only lscommons.js and lspushpage.js that need to be copied, but then I copied all the lib.

    By the way, how do I compile the *.java file?

  39. Ashwini Says:

    I tried each and every step as mentioned above. My LS is working perfectly but still not able to deploy the application. No error message was shown in the logs, but still getting Error 404. My HelloWorld folder was initially under adapters folder, but i then switched under /pages directory. So getting Loading… html page only. Please suggest.

    Thanks for the help provided in this regard.

Leave a Reply



Copyright 2014 Comet Daily, LLC. All Rights Reserved