📜 ⬆️ ⬇️

Duplex asynchronous data exchange for the web, mobile and desktop in one implementation

To send data from the server to the client, it does not matter whether it is the web, mobile or desktop, there are enough technicians. But the problem is that they are all different and if you need to implement an alert about the same event for clients on all major platforms, you will have to duplicate this same alert code. That's why I want to share with the community my practice of working with a single product called LightStreamer .

I will say right away - this is not advertising and I have no relation to the developers and will not receive any remuneration for my work (except moral, for sharing my experience).

So, LightStreamer is a server running on Java and as a result it can be run on both Windows and Linux machines + if development is done on Amazon, then you can use the ready Amazon Machine Image with LightStreamer on board download.lightstreamer.com .
The installation package (actually the archived folder) already contains a demo license, the limitations of which are reduced to only 20 simultaneously connected clients, which, you see, is quite enough for development, but if not, you can order an evaluation without limitations for 60 days. Here is a list of available licenses .

Installation instructions are set out in /Lightstreamer/GETTING_STARTED.TXT which is located inside the archive. Everything is very simple (I will describe for Windows):
- unpack, preferably to the root of the disk because the archive contains fairly long file paths;
- we specify TCP ports on which the server will hang in /Lightstreamer/conf/lightstreamer_conf.xml, by default 8080 and 8888;
- in /Lightstreamer/bin/windows/LS.bat in the JAVA_HOME variable we specify where the JDK is installed (if not installed, install);
- and start the server / Lightstreamer/bin/windows/Start_LS_as_Application.bat.
For the test, open http: // localhost: 8080 (we specify the same port that was specified in /Lightstreamer/conf/lightstreamer_conf.xml) and should see the welcome page with links to preinstalled demos.
It is also possible instead of HTTP to use HTTPS and clustering with a load balancer.
')
Well, the server is installed, but there’s little use - you need to teach it to handle our requests and give answers. For this, there is an adapter mechanism (something like plug-ins). That is, we need to write an adapter that will process requests from our clients and let the server know that such an adapter exists to send requests to it.

Writing adapter

The / Lightstreamer / DOCS-SDKs / folder contains the SDK. To write an adapter in .NET, you need to implement the Lightstreamer.Interfaces.Data.IDataProvider interface from /Lightstreamer/DOCS-SDKs/sdk_adapter_dotnet/lib/DotNetAdapter_N2.dll
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")) { new Thread(new ThreadStart(Run)).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)); } } } 

Running adapter

To start we need a console aplikuha
 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); } } } 

Filling adapter to server

In the folder / Lightstreamer / adapters / create a new folder and copy into it / Lightstreamer/DOCS-SDKs/sdk_adapter_remoting_infrastructure/lib/ls-proxy-adters.jar. In the same place, we create a new /lib/adapters.xml file with content.
 <?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>com.lightstreamer.adapters.remote.data.RobustNetworkedDataProvider</adapter_class> <classloader>log-enabled</classloader> <param name="request_reply_port"> 6661</param> <param name="notify_port"> 6662</param> </data_provider> </adapters_conf> 

The name can beat anyone - it will be indicated when writing the client and that's it. As you can see the ports are the same as when starting the adapter.

Client writing

For example, give the simplest JavaScript client
 <html> <head> <script src="http://cdnjs.cloudflare.com/ajax/libs/require.js/1.0.7/require.min.js"></script> <script src="https://code.jquery.com/jquery-2.1.0.min.js"></script> <script src="C:/Lightstreamer/DOCS-SDKs/sdk_client_javascript/lib/lightstreamer.js"></script> <script> require(["LightstreamerClient","Subscription","StaticGrid"],function(LightstreamerClient,Subscription,StaticGrid) { var lsClient = new LightstreamerClient("http://localhost:8080", "HelloWorld"); lsClient.connect(); var lsSubscription = new Subscription("MERGE",['greetings'],['greetings', 'message', 'timestamp']); lsSubscription.addListener({ onItemUpdate: function(updateObject) { $("#message").text('Message=' + updateObject.getValue("message")); $("#timestamp").text('TimeStamp=' + updateObject.getValue("timestamp")); } }); lsClient.subscribe(lsSubscription); }); </script> </head> <body> <span id="message"></span><br/> <span id="timestamp"> </span> </body> </html> 

Result

And as a result we received automatically updated data on the client:

image
In order for a client to receive unique data that relates to him, for example messages in a chat, instead of just 'greetings' (the second parameter), you need to transfer the user’s ID and on the adapter side to retrieve his messages on this side.

 new Subscription("MERGE",['userID123'],['greetings', 'message', 'timestamp']) 

You can also transfer not only one parameter, but several parameters, separated by a comma, a colon, and so on. and accordingly, on the adapter side, all this is parsing.
In the process of development, I encountered the inconvenience of debug on a server on which there is no studio and found out that instead of localhost in the DataAdapterLauncher class, you can transfer the address of the machine where the server is and thus it is possible without having a local server to debug.

At last

Judging by the www.lightstreamer.com/doc adapter, you can write to:

A list of platforms for customers more:

PS
Adapter pages for example on github 'e.

Source: https://habr.com/ru/post/220343/


All Articles