Lucid’s crosstalk system is similar to D-Bus; it provides a simple way for two application instances to communicate with one another. Lucid’s adaptation adds the ability to send and recieve messages between two different users as well. The api is influenced from Dojo’s dojo.subscribe and dojo.publish methods.
The way messages are sent depend on the destination, but the API acts the same either way. Each message sent can have a user, application, and instance as it’s destination. Both routes have a message dispacher that takes messages from a message queue and routes them to the other application. If the message only specifies an application, and the application is not running, then the dispacher will start the application and pass the message to it. If the message specifies a specific application instance, and that instance is not listening for messages, then the message is dropped.
When done locally, the message is pushed into a message queue by the API to be processed by the dispacher.
In the event that the message specifies a different user then the current, the message is sent to the server. When the other person starts the desktop, and the message checker polls the server, then the message checker pushes the message into it’s message queue to be handled by the dispacher. The dispacher then sends the message to the application.
Messages are separated into topics that can be subscribed to. For example, if you were writing a multiplayer checkers game, you could have a “movements” topic and a “chat” topic.
When subscribing to topics, you provide a handler function. This function will handle any messages recieved by the dispacher.
It’s important that you subscribe to topics inside of the init method of your app, since the dispacher may launch your app to send it a message. If it does not find any subscriptions after the init method is called, then it will kill the app. Applications launched by the dispacher are passed a crosstalk argument, which is set to true.
Subscribing to topics is pretty simple:
this.myTopicSubscription = desktop.crosstalk.subscribe("myTopic", dojo.hitch(this, "myTopicHandler"), this.sysname);
The dispacher will pass a single argument to the handler function, that will contain the message. Messages are always objects, their keys being specified by the application that sent it.
myTopicHandler: function(msg){
desktop.dialog.notify(msg.someKey);
},
Messages also have a _crosstalk property, that has information about where the message came from:
Unsubscribing from a topic will tell the dispacher to stop sending messages to the handler function:
desktop.crosstalk.unsubscribe(this.myTopicSubscription);
To publish a message, use the publish method.
To publish messages to a specific user, all you need to do is speicfy the userid and the app's system name, as well as the topic and message.
var message = {
someKey: "Some Value",
foo: "bar"
};
var userid = 5;
desktop.crosstalk.publish("myTopic", message, userid, this.sysname);
To publish a message between two instances of an app being run by the same user, you need to pass null as the userid, and provide a system name and app instance.
var message = {
someKey: "Some Value",
foo: "bar"
};
var instance = 2;
desktop.crosstalk.publish("myTopic", message, null, this.sysname, instance);
This feature is handy if you want to check if the message has been sent to the user or not. If it has been sent, it will not exist on the database. You need to pass a event ID and a callback. The callback will be called with 'true' (it exists, not sent) or 'false' (it doesn't exist, sent).
var message = {
someKey: "Some Value",
foo: "bar"
};
var instance = 2;
desktop.crosstalk.publish("myTopic", message, null, this.sysname, instance, dojo.hitch(this, function(id) {
setTimeout(dojo.hitch(this, function() {
desktop.crosstalk.exists(id, dojo.hitch(this, function(exists) {
if(exists) alert('event exists! message not yet sent');
else alert('event doesn't exist! message sent!');
}));
}), (desktop.config.crosstalkPing * 2));
}));
This is handy if you want an event sent to the user, but if the user isn't logged in or responding to crosstalk, it might as well be cancelled.
var message = {
someKey: "Some Value",
foo: "bar"
};
var instance = 2;
desktop.crosstalk.publish("myTopic", message, null, this.sysname, instance, dojo.hitch(this, function(id) {
setTimeout(dojo.hitch(this, function() {
desktop.crosstalk.exists(id, dojo.hitch(this, function(exists) {
if(exists){
desktop.crosstalk.cancel(id);
}
else alert('event doesn't exist! message sent!');
}));
}), (desktop.config.crosstalkPing * 2));
}));