SitePen Support
Comet Support by SitePen

“Hello World” for .NET with Lightstreamer

by Alessandro AlinoneApril 14th, 2008

After publishing the article “Hello World” with Lightstreamer, I received many requests to release a version of that tutorial for .NET developers. Therefore, in this installment we will work on a .NET port of the Java Data Adapter that we illustrated in the previous article. In particular, both a C# version and a Visual Basic version will be shown.

Let’s get started

First, please take a look at the previous installment, 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 C# and Visual Basic equivalents. 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 Flex, instead of HTML, on the client side. Or we could use the C# Adapter on the server side and use Java, instead of HMTL or Flex, on the client side. Basically, all the combinations of languages and technologies on the client side and on the server side are supported.

As in the previous installment, these examples will be based on Lightstreamer Server v. 3.4 and Lightstreamer Web Client v. 4.2.

Give me some .NET interfaces!

Lightstreamer Server is written in Java, so its native Adapter interfaces are Java based. The .NET interfaces are added through the Lightstreamer Adapter Remoting Infrastructure (ARI). Let’s have a look at it.

Lightstreamer ARI

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 very standard TCP sockets.

But—here is some magic—if your remote Data Adapter is based on .NET, you can forget about direct socket programming, and leverage a ready-made library that exposes a higher level .NET interface. So, you will simply have to implement this .NET interface. Ok, let’s recap… The Proxy Data Adapter converts from a Java interface to TCP sockets. The .NET library converts from TCP sockets to a .NET interface. Clear enough?

Creating the C# Data Adapter

Let’s start with C#. Feel free to skip this section if you are only interested in the Visual Basic example (I will replicate the same comments on the code).

We should implement two classes. One (which we will call DataAdapterLauncher) contains the application’s Main and initializes the DataProviderServer (the provided piece of code that implements the Network Protocol). The other (which we will call HelloWorldAdapter) implements the actual Adapter interface.

  1. Create a new C# project (I used Microsoft’s Visual C# 2008 Express Edition).
  2. From the “New Project…” wizard, choose the “Console Application” template. Let’s use “adapter_csharp” as the project name.
  3. From the “Solution Explorer”, delete the default Program.cs, then add a reference to the Lightstreamer .NET library: go to the “Browse” tab of the “Add Reference” dialog and point to the DotNetAdapter_N2.dll file, which you can find in the “Lightstreamer\DOCS-SDKs\sdk_adapter_dotnet\lib\dotnet_2.0″ folder of your Lightstreamer installation.

DataAdapterLauncher

Add a new class (let’s call its file DataAdapterLauncher.cs). Replace the source code with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Net.Sockets;
 
using Lightstreamer.DotNet.Server;
 
public class DataAdapterLauncher
{
  public static void Main(string [] args)
  {
    string host= "localhost";
    int reqrepPort = 6661;
    int notifPort = 6662;
 
    try
    {
      DataProviderServer server = new DataProviderServer();
      server.Adapter = new HelloWorldAdapter();
 
      TcpClient reqrepSocket = new TcpClient(host, reqrepPort);
      server.RequestStream = reqrepSocket.GetStream();
      server.ReplyStream = reqrepSocket.GetStream();
 
      TcpClient notifSocket = new TcpClient(host, notifPort);
      server.NotifyStream = notifSocket.GetStream();
 
      server.Start();
      System.Console.WriteLine("Remote Adapter connected to Lightstreamer Server.");
      System.Console.WriteLine("Ready to publish data...");
    } 
    catch (Exception e)
    {
      System.Console.WriteLine("Could not connect to Lightstreamer Server.");
      System.Console.WriteLine("Make sure Lightstreamer Server is started before this Adapter.");
      System.Console.WriteLine(e);
    }
  }
}

This code creates a DataProviderServer instance and assigns a HelloWorldAdapter instance (which we will define below) to it. Then, it creates two TCP client sockets, because the Proxy Data Adapter, to which our remote .NET Adapter will connect, needs two connections (but as I said, after creating these sockets, you don’t have to bother with reading and writing, as these operations are automatically handled by the DataProviderServer). Let’s use TCP ports 6661 and 6662. Assign the stream of the first socket to the RequestStream and ReplyStream properties of the DataProviderServer. Assign the stream of the second socket to the NotifyStream property of the DataProviderServer. Finally, you start the DataProviderServer.

HelloWorldAdapter

Now add another class (call its file HelloWorld.cs). Replace the source code with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Collections;
using System.Threading;
 
using Lightstreamer.Interfaces.Data;
 
public class HelloWorldAdapter : IDataProvider
{
  private IItemEventListener _listener;
  private volatile bool go;
 
  public void Init(IDictionary parameters, string configFile)
  {
  }
 
  public bool IsSnapshotAvailable(string itemName)
  {
    return false;
  }
 
  public void SetListener(IItemEventListener eventListener)
  {
    _listener = eventListener;
  }
 
  public void Subscribe(string itemName)
  {
    if (itemName.Equals("greetings"))
    {
      Thread t = new Thread(new ThreadStart(Run));
      t.Start();
    }
  }
 
  public void Unsubscribe(string itemName)
  {
    if (itemName.Equals("greetings"))
    {
      go = false;
    }
  }
 
  public void Run()
  {
    go = true;
    int c = 0;
    Random rand = new Random();
 
      while (go)
      {
        IDictionary eventData = new Hashtable();
        eventData["message"] = c % 2 == 0 ? "Hello" : "World";
        eventData["timestamp"] = DateTime.Now.ToString("s");
        _listener.Update("greetings", eventData, false);
        c++;
        Thread.Sleep(1000 + rand.Next(2000));
      }
  }
}

The HelloWorldAdapter class implements the IDataProvider interface (which is the .NET remote equivalent of the Java DataProvider interface).

Implement the SetListener method to receive a reference to the server’s listener that you will use to inject events.

Then, implement the Subscribe method. When the “greetings” item is subscribed to by the first user, the 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, the Adapter is notified through the Unsubscribe call. In this case we stop the publisher thread for that item. If a new user re-subscribes to “greetings”, the Subscribe method is called again. As already mentioned in the previous installment, this approach avoids consuming processing power for items nobody is currently interested in.

The Run method is executed within the thread started by Subscribe. Its code is very simple. We create a Hashtable containing a message (alternating “Hello” and “World”) and the current timestamp. Then we inject the Hashtable into the server through the listener. We wait for a random time between 1 and 3 seconds, and we are ready to generate a new event.

Save and build

From the File menu, choose “Save All“. Type a location, for example: “c:\”.

From the Build menu, choose “Build Solution“. Your C# Data Adapter is now compiled. If you used the path above, you will find your executable file under “C:\adapter_csharp\adapter_csharp\bin\Release”. It is called “adapter_csharp.exe“. But be patient and don’t start it now, because you have to configure and start the Lightstreamer Server first. You can skip the section below, dedicated to VB, and go straight to the “Deploy the Proxy Adapter” section.

Creating the Visual Basic Data Adapter

Now let’s work with Visual Basic instead of C#.

We will create a module (DataAdapterLauncher) which contains the application’s Main and initializes the DataProviderServer (the provided piece of code that implements the Network Protocol). Then we will create a class (HelloWorldAdapter) that implements the actual Adapter interface.

  1. Create a new VB project (I used Microsoft’s Visual Basic 2008 Express Edition).
  2. From the “New Project…” wizard, choose the “Console Application” template. Let’s use “adapter_vb” as the project name.
  3. From the “Solution Explorer”, delete the default Module1.vb, then add a reference to the Lightstreamer .NET library: go to the “Browse” tab of the “Add Reference” dialog and point to the DotNetAdapter_N2.dll file, which you can find in the “Lightstreamer\DOCS-SDKs\sdk_adapter_dotnet\lib\dotnet_2.0″ folder of your Lightstreamer installation.

DataAdapterLauncher

Add a new module (let’s call its file DataAdapterLauncher.vb). Replace the source code with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Imports System.Net.Sockets
 
Imports Lightstreamer.DotNet.Server
 
Module Module1
  Sub Main()
    Dim host As String = "localhost"
    Dim reqrepPort As Integer = 6661
    Dim notifPort As Integer = 6662
 
    Try
      Dim server As New DataProviderServer()
      server.Adapter = New HelloWorldAdapter()
 
      Dim reqrepSocket As New TcpClient(host, reqrepPort)
      server.RequestStream = reqrepSocket.GetStream()
      server.ReplyStream = reqrepSocket.GetStream()
 
      Dim notifSocket As New TcpClient(host, notifPort)
      server.NotifyStream = notifSocket.GetStream()
 
      server.Start()
      System.Console.WriteLine("Remote Adapter connected to Lightstreamer Server.")
      System.Console.WriteLine("Ready to publish data...")
    Catch e As Exception
      System.Console.WriteLine("Could not connect to Lightstreamer Server.")
      System.Console.WriteLine("Make sure Lightstreamer Server is started before this Adapter.")
      System.Console.WriteLine(e)
    End Try
  End Sub
End Module

This code creates a DataProviderServer instance and assigns a HelloWorldAdapter instance (which we will define below) to it. Then, it creates two TCP client sockets, because the Proxy Data Adapter, to which our remote .NET Adapter will connect, needs two connections (but as I said, after creating these sockets, you don’t have to bother with reading and writing, as these operations are automatically handled by the DataProviderServer). Let’s use TCP ports 6661 and 6662. Assign the stream of the first socket to the RequestStream and ReplyStream properties of the DataProviderServer. Assign the stream of the second socket to the NotifyStream property of the DataProviderServer. Finally, start the DataProviderServer.

HelloWorldAdapter

Now add a class (call its file HelloWorld.vb). Replace the source code with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Imports System.Collections
Imports System.Threading
 
Imports Lightstreamer.Interfaces.Data
 
Public Class HelloWorldAdapter
  Implements IDataProvider
  Private _listener As IItemEventListener
  Private go As Boolean
 
  Public Sub Init(ByVal parameters As IDictionary, ByVal configFile As String) Implements IDataProvider.Init
  End Sub
 
  Function IsSnapshotAvailable(ByVal itemName As String) As Boolean Implements IDataProvider.IsSnapshotAvailable
    Return False
  End Function
 
  Public Sub SetListener(ByVal eventListener As IItemEventListener) Implements IDataProvider.SetListener
    _listener = eventListener
  End Sub
 
  Public Sub Subscribe(ByVal itemName As String) Implements IDataProvider.Subscribe
    If itemName.Equals("greetings") Then
      Dim t As New Thread(AddressOf Run)
      t.Start()
    End If
  End Sub
 
  Public Sub Unsubscribe(ByVal itemName As String) Implements IDataProvider.Unsubscribe
    If itemName.Equals("greetings") Then
      go = False
    End If
  End Sub
 
  Public Sub Run()
    go = True
    Dim c As Integer = 0
    Dim rand As New Random()
 
    While go
      Dim eventData As IDictionary = New Hashtable()
      eventData("message") = IIf(c Mod 2 = 0, "Hello", "World")
      eventData("timestamp") = DateTime.Now.ToString("s")
      _listener.Update("greetings", eventData, False)
      c += 1
      Thread.Sleep(1000 + rand.Next(2000))
    End While
  End Sub
End Class

The HelloWorldAdapter class implements the IDataProvider interface (which is the .NET remote equivalent of the Java DataProvider interface).

Implement the SetListener subroutine to receive a reference to the server’s listener that you will use to inject events.

Then, implement the Subscribe subroutine. When the “greetings” item is subscribed to by the first user, the Adapter receives that subroutine call and starts a thread that will generate the real-time data. If more users subscribe to the “greetings” item, the Subscribe subroutine is not called any more. When the last user unsubscribes from this item, the Adapter is notified through the Unsubscribe call. In this case we stop the publisher thread for that item. If a new user re-subscribes to “greetings”, the Subscribe subroutine is called again.

The Run subroutine is executed within the thread started by Subscribe. Its code is very simple. We create a Hashtable containing a message (alternating “Hello” and “World”) and the current timestamp. Then we inject the Hashtable into the server through the listener. We wait for a random time between 1 and 3 seconds, and we are ready to generate a new event.

Save and build

From the File menu, choose “Save All“. Type a location, for example: “c:\”.

From the Build menu, choose “Build adapter_vb“. Your VB Data Adapter is now compiled. If you used the path above, you will find your executable file under “C:\adapter_vb\adapter_vb\bin\Release”. It is called “adapter_vb.exe“. As for the C# Adapter, don’t start it now, because you have to configure and start the Lightstreamer Server first.

Deploying the Proxy Adapter

Now that our remote Data Adapter is ready, we need to deploy and configure the provided Proxy Adapter within Lightstreamer Server.

Lightstreamer treeGo to the “adapters” folder of your Lightstreamer Server installation. You could already have a “StockList” folder (containing a pre-installed demo Adapter) and a “HelloWorld” Adapter (if you followed the Java tutorial of the previous installment). Now create a “ProxyHelloWorld” folder inside “adapters”, and a “lib” folder inside “ProxyHelloWorld”.

Copy the “ls-proxy-adapters.jar” file from “Lightstreamer/DOCS-SDKs/sdk_adapter_remoting_infrastructure/lib” to “Lightstreamer/adapters/ProxyHelloWorld/lib”.

Create a new file in “Lightstreamer/adapters/ProxyHelloWorld”, call it “adapters.xml“, and use the following contents:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0"?>
 
<adapters_conf id="PROXY_HELLOWORLD">
 
  <metadata_provider>
    <adapter_class>com.lightstreamer.adapters.metadata.LiteralBasedProvider</adapter_class>
  </metadata_provider>
 
  <data_provider>
    <adapter_class>com.lightstreamer.adapters.remote.data.NetworkedDataProvider</adapter_class>
    <param name="request_reply_port">6661</param>
    <param name="notify_port">6662</param>
  </data_provider>
 
</adapters_conf>

You have just deployed a new Java Adapter pair, where the Metadata Adapter is a default one (called “LiteralBasedProvider”) and the Data Adapter is the Proxy Adapter (called “NetworkedDataProvider”). This Adapter pair will be referenced by the clients as “PROXY_HELLOWORLD“.

As a final configuration, let’s tell our Web client to use this new Adapter pair, rather than those we developed last time. So just edit the “index.htm” page of the Hello World front-end (last time we deployed it under “Lightstreamer/pages/HelloWorld”) and replace:

  engine.connection.setAdapterName("HELLOWORLD");

with:

  engine.connection.setAdapterName("PROXY_HELLOWORLD");

Running the application

Now we have all the pieces ready. Let’s enjoy the results.

Start your Lightstreamer Server. When it’s up, run either the C# or the VB Remote Adapter.

Open a browser window and go to: http://localhost:8080/HelloWorld/

Final notes

Starting from these very simple code fragments we have developed in these two installments (covering basic JavaScript, Java, C#, and VB), I encourage you to experiment and create more complex applications. The full API references for all these languages are available from the links below:

All the source code described in this article is available for download.

As I already outlined in the previous installment, we used the free Moderato edition of Lightstreamer for this tutorial. Its main limitation, with respect to the commercial editions, is that it only allows 1 update/sec for each subscribed item (but you can subscribe to as many items as you want). If you need to experiment with higher-frequency events for the same item, you can use a free evaluation license of Lightstreamer Presto or Vivace.

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

20 Responses to ““Hello World” for .NET with Lightstreamer”

  1. jingye800 Says:

    hello Alessandro, can you tell me the theory about the Lightstreamer interactionDemo for .net, i am very interest in it, thank you very much!

  2. jingye800 Says:

    can you give me a small demo for the .net adapter?

  3. Alessandro Alinone Says:

    @jingye800: There are currently two public examples of .NET Lightstreamer Adapters. One is the “Hello World” example of this article. The other is the Stock List Demo, which you can find in any Lightstreamer distribution under the “Lightstreamer\DOCS-SDKs\sdk_adapter_dotnet\examples” folder.
    If anybody else makes available any Adapter example, please let me know, so that it can be shared with the Lightstreamer community.

  4. ethar1 Says:

    Dear Alessandro Alinone , Thanks very much for your great efferots , your article was very helpful and explain many concepts.

    just one you may missed it to copy LS folder ( js ) to working directory of index.htm.

    Could you please explain ( in another article ) how to creat client in VB desktop application?

    is there is any example to show how?

    your kind reply will be highly appreciated.
    Thanks.

  5. FCIDeveloper Says:

    Thank you for your nice article , but when i deployed the application & run it , i got the following alert error
    “1:11:0:22,656 ER bind unable to find the engine .Retrying .If the problem persists , please check your configuration”

    So, how can we solve it?

    Thank You

  6. LSUser Says:

    hello Alessandro,
    can You tell me what is the solution for this alert which appears after i deployed the applicationand rub it
    “4:11:11:28,796 ER createEngine The call of createEngine methods after the body onload event is supported only for DOM2 browsers.You might have reached this point , due to solw page downloads.”

    Best Regards

  7. Bren002 Says:

    Hi Alessadro,

    Thank you for your nice article, but I get the following alert message when deploying the application and run it:

    “1:11:0:57,257 ER bind unable to find the engine .Retrying .If the problem persists , please check your configuration”

    I followed exactly the steps shown in the article, what does this error message means?

    Thank you.

  8. Mario Says:

    Hi Alessadro,

    Thanks for the article, but I also get the ‘ER bind Unable to find the Engine’ error.
    Has anyone found a solution for it yet?

    MK

  9. Alessandro Alinone Says:

    Hi guys,

    It seems you probably didn’t deploy the front-end resources correctly, as explained in the first article. Please make sure that the “Hello World” example explained in the first article works correctly, before moving to the .NET version (you don’t need to compile any Java code, as the first article provides the ready binaries too).

    Typically, the “bind unable to find the engine” error happens when the createEngine() call does not specify the right path for the Lightstreamer libraries as the second parameter. In the example above, the call that you find inside index.htm is:

    page.createEngine(”HelloWorldApp”, “LS”, “SHARE_SESSION”);

    This means that in the folder containing index.htm, an “LS” folder must exist containing all the Lightstreamer libraries.

    Hope that helps.

    -Alessandro

  10. Guillermo Says:

    Hi.

    I’m following these instructions, but they seem to be incomplete.

    The section “Deploying the Proxy Adapter” doesn’t mention what files from bin\Debug from the C# project need to be copied to the Lightstreamer\adapters\Proxy_HelloWorld folder.

    I copied all anyway, restarted the server, updated index.htm to point to PROXY_HELLOWORLD, but I get a browser error “IE cannot display the page”.

    Before this, I deployed the Java version of the adapter and started it successfully.

    In the Lightstreamer.log file I see these entries that don’t seem to be completed:

    22-Apr-09 07:16:27,828 |INFO |.remote.transport.SocketTransport|uest/Reply Socket Connector|Waiting for a connection on port 6661…
    22-Apr-09 07:16:27,828 |INFO |.remote.transport.SocketTransport|Notify Socket Connector |Waiting for a connection on port 6662…

    And these sentences from the C# project that should be displayed somewhere, I assume the log file, are nowhere to be seen:

    System.Console.WriteLine(”Remote Adapter connected to Lightstreamer Server.”);
    System.Console.WriteLine(”Ready to publish data…”);

    Is LS server supposed to launch the adapter_csharp.exe program? At what point? If not, how is that program supposed to be started?

    Finally, I removed the folder Proxy_HelloWorld from Lightstreamer\adapters on the server, restarted the server, changed the index.htm client page to point back to HELLOWORLD, and it works fine.

    Could somebody explain how this proxy adapter is supposed to work, or how to make the demo run successfully?

    Thanks in advance.
    Guillermo

  11. Guillermo Says:

    Reply to my previous posting:

    Never mind. I started the console app manually and it all started working.

    I’d still like to know what specific files from the C# project are supposed to be deployed in the adapters folder, whether the .exe and .dll files only or the .pdb as well.

    Thanks for the demo. Nice job.
    -Guillermo

  12. Alessandro Alinone Says:

    Guillermo,

    As explained in the article, you must copy only “ls-proxy-adapters.jar” and “adapters.xml” in the “ProxyHelloWorld” folder inside the “adapters” folder.

  13. Vladimir Says:

    Hi, thank you for this article it’s very helpfull

    I wanna build web chat application using lightstreamer and ASP.NET..can you help with the architecture. How will Lightstreamer work along the asp.net server..etc

    Thanks

  14. No Idon't Says:

    Hi all
    Thank you for your nice article, but I get the following alert message when deploying the application and run it:

    “1:11:0:57,257 ER bind unable to find the engine .Retrying .If the problem persists , please check your configuration”
    Help me

  15. No Idon't Says:

    Help

    “1:11:0:57,257 ER bind unable to find the engine .Retrying .If the problem persists , please check your configuration”

  16. Alessandro Alinone Says:

    Hi,

    It’s easier if you post any questions to the Lightstreamer forums, to take benefit of thread-based organizations: http://www.lightstreamer.com/forum

  17. Jeff Dyer Says:

    I have built the adapter_csharp but the I start lightstremaer using the start LS as application batch file, the file hangs at the end saying

    waiting for a connection on port 6662…
    waiting for a connection on port 6661…

    and the port 8080 server does not start.

    But if I manually run the adapter_csharp.exe in the lib folder the lightstreamer comes alive and does work. Why doesn’t the .exe load itself - do I have to set the startup object in the project configuration??

    Thanks

  18. Jeff Dyer Says:

    Follow up - I seem to have the same issue as Guillermo above, I have to start csharp_adapter.exe manually while the start LS as application.bat file is waiting

  19. Alessandro Alinone Says:

    Answered here: http://www.lightstreamer.com/vb/showthread.php?t=608

  20. MervinKumar Says:

    Do we Need JSharp to be Installed for DotNet to Run this Demo.

Leave a Reply



Copyright 2014 Comet Daily, LLC. All Rights Reserved