Hi,
Here is simple example of how to integrate lightstreamer with gwt.
Generic class that manages dynamic control over group&schema:
public abstract class NonVisualGWTClient {
public enum SourceType {
RAW, MERGE, DISTINCT, COMMAND;
}
protected JavaScriptObject nvt;
protected String configuration;
protected HashMap<String, Integer> group = new HashMap<String, Integer>();
protected HashMap<String, Integer> schema = new HashMap<String, Integer>();
private JavaScriptObject page;
protected String sourceType = SourceType.RAW.name();
private JavaScriptObject config;
private boolean isInitialized = false;
public NonVisualGWTClient(String configuration) {
this.configuration = configuration;
}
public boolean isInitialized() {
return isInitialized;
}
public void setInitialized(boolean isInitialized) {
this.isInitialized = isInitialized;
}
private native JavaScriptObject createPushPage() /*-{
var page = new $wnd.PushPage();
return page;
}-*/;
private native void init(JavaScriptObject map, JavaScriptObject page) /*-{
try {
page.context.setDomain(map['domain']);
page.onEngineCreation = function(engine) {
engine.connection.setLSHost(map['host']);
engine.connection.setLSPort(map['port']);
engine.connection.setAdapterName(map['adapter_root']);
engine.changeStatus(map['engine_status']);
}
page.bind();
page.createEngine("app", map['ls_home'], "SHARE_SESSION");
} catch(error) {
alert(error);
}
}-*/;
private native JavaScriptObject getNVT(String[] group, String[] schema, String sourceType) /*-{
var nonVisualTable = new $wnd.NonVisualTable(group, schema, sourceType);
return nonVisualTable;
}-*/;
/**
* If the ls client is not initialized yet, restart() is delayed and is
* called when the client is initialized
* */
public void restart() {
if (isInitialized) {
final String[] schema = NonVisualGWTClient.this.schema.keySet().toArray(new String[0]);
final JavaScriptObject nvt = getNVT(NonVisualGWTClient.this.group.keySet().toArray(new String[0]), schema,
NonVisualGWTClient.this.sourceType);
this.nvt = nvt;
restart(nvt, this, page, config, schema);
}
}
protected native void debug(String msg) /*-{
alert(msg);
}-*/;
private native void restart(JavaScriptObject nvt, NonVisualGWTClient thiz, JavaScriptObject page, JavaScriptObject map, String [] schema) /*-{
nvt.setDataAdapter(map['adapter_name']);
nvt.setSnapshotRequired(false);
this.@com.trinitas.ls.client.NonVisualGWTClient::nvt.onItemUpdate = function(item, itemUpdate, itemName) {
for (i=0;i<schema.length;i++) {
try {
var msg = itemUpdate.getNewValue(schema[i]);
if (msg !=null) {
thiz.@com.trinitas.ls.client.NonVisualGWTClient::onMessage(Ljava/lang/String;Ljava/lang/String :Smile_Ad: (msg, schema[i]);
}
} catch(error) {
alert(error);
}
}
}
page.addTable(nvt,"tnvt");
}-*/;
protected abstract void onMessage(String message, String schemaId);
public void addToShema(String item) {
Integer count = schema.get(item);
if (count == null || count == 0) {
schema.put(item, 1);
} else {
count = count + 1;
schema.put(item, count);
}
}
public Integer removeFromShema(String item) {
Integer count = schema.get(item);
if (count <= 1) {
schema.remove(item);
} else {
count = count - 1;
schema.put(item, count);
}
return count;
}
public void stop() {
group.clear();
schema.clear();
restart();
}
public void addToGroup(String item) {
Integer count = group.get(item);
if (count == null || count == 0) {
group.put(item, 1);
} else {
count = count + 1;
group.put(item, count);
}
}
public void removeFromGroup(String item) {
Integer count = group.get(item);
if (count <= 1) {
group.remove(item);
} else {
count = count - 1;
group.put(item, count);
}
}
public void initialize(final SourceType type, final AsyncCallback<Void> callback) {
loadLSProperties(new LightStreamerConfigHandler() {
@Override
public void afterLoad(JavaScriptObject map) {
try {
config = map;
NonVisualGWTClient.this.sourceType = type.name();
if (page == null) {
page = createPushPage();
}
final String [] group = NonVisualGWTClient.this.group.keySet().toArray(new String[0]);
final String [] schema = NonVisualGWTClient.this.schema.keySet().toArray(new String[0]);
nvt = getNVT(group, schema, NonVisualGWTClient.this.sourceType);
if (!isInitialized) {
isInitialized = true;
init(config, page);
}
restart(nvt, NonVisualGWTClient.this, page, config, schema);
callback.onSuccess(null);
} catch (final Throwable e) {
callback.onFailure(e);
}
}
});
}
public HashMap<String, Integer> getGroup() {
return group;
}
//
// public void setGroup(HashSet<String> group) {
// this.group = group;
// }
public HashMap<String, Integer> getSchema() {
return schema;
}
// public void setSchema(HashSet<String> schema) {
// this.schema = schema;
// }
// protected abstract void setOnItemUpdate();
private void loadLSProperties(final LightStreamerConfigHandler handler) {
final JavaScriptObject map = readProperties(configuration);
handler.afterLoad(map);
}
private JavaScriptObject readProperties(String responseText) {
final JSONObject map = new JSONObject();
int endLineIndex;
for (int startIndex = 0; startIndex < responseText.length(); startIndex = endLineIndex + 1) {
endLineIndex = responseText.indexOf('\n', startIndex);
final String line = responseText.substring(startIndex, endLineIndex == -1 ? responseText.length() : endLineIndex).trim();
if (!"".equals(line) && !line.startsWith("#")) {
addNameValue(line, map);
}
if (endLineIndex == -1) {
break;
}
}
return map.getJavaScriptObject();
}
private void addNameValue(String line, JSONObject map) {
final int equalsIndex = line.indexOf('=');
final String key = line.substring(0, equalsIndex).trim();
final int hashIndex = line.indexOf('#');
final String value = line.substring(equalsIndex + 1, hashIndex == -1 ? line.length() : hashIndex).trim();
map.put(key, new JSONString(value));
}
}
public interface LightStreamerConfigHandler {
public void afterLoad(JavaScriptObject map);
}
For your project you must create class that consumes the messages:
public class MyGWTClient extends NonVisualGWTClient {
public MyGWTClient() {
super(ServiceUtils.getClientResource().lsconfig().getText());
// add here default static subscriptions - not mandatory
addToGroup("item1");
addToShema("property1");
}
@Override
protected void onMessage(String msg, String schemaId) {
// process message according its schema - here you may have many //messages coming but since it is js it is not a problem
// example how to process message:
if ("property1".equals(schemaId)) {
// call process method for this type of message - I use eventBus to fire the //event with that message, so the code that consumes the messages is completely //independent from ls.
}
}
}
I use ClientBundle to load the initial configuration of ls client.
@Source("resources/ls/lsconfig.properties")
public TextResource lsconfig();
Here is sample properties file:
domain=mycomain
host=myhost
port=8888
adapter_root=TEST
adapter_name=JMSADAPTER
ls_home=/ls/ <!-- this is where ls config files are placed - lspushpage.js,lsengine.html,lspushpage.js and so on... -->
engine_name=engine
engine_status=STREAMING
Example how to use :
MyGWTClient client = new MyGWTClient();
client.initialize(SourceType.RAW, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable arg0) {
}
@Override
public void onSuccess(Void arg0) {
}
});
client.addToGroup("item2");
client.addToGroup("item3");
client.addToSchema("property2");
client.addToSchema("property3");
client.addToSchema("property4");
client.restart();// this makes the ls to subscribe to the above group&schema + the old ones
// cleaning schema and group
client.removeFromSchema("property2");
client.removeFromGroup("item1");
client.restart();