PUB/SUB
The publish/subscribe pattern is useful when your applications need the users to subscribe to the topics that you are about to publish. You can have very good control with XSockets since you can select subsets of subscribers very easy to get more fine grained control.
You will see more about this powerful feature combined with PUB/SUB below.
Topic Hierarchy
As of XSockets 5.0.3
Pub/Sub supports topic as hierarchies. This means that you can define subscriptions like:
home/kitchen/temperature
home/kitchen/light
Each hierarchy is separated by a /
and you can use wildcards +
and #
The +
sign represents a single level like:
home/+/temperature
The #
sign represents all remaining level like:
home/kitchen/#
How to publish data to subscribers
If you just want to send a message to the publisher/caller of the method, use Publish
The big difference between Publish
and Invoke
is that with Publish
the message only will arrive at the client if the client has a Subscription
registered on the server.
Server
//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;
//Publish a message to the caller
this.Publish("Hello to caller from server", "chatmessage");
Client
Client - JavaScript
conn.controller('chat').subscribe('chatmessage', function(data){
console.log(data);
});
Client - C#
conn.Controller("chat").Subscribe<string>("chatmessage", data => Console.WriteLine(data) );
How to publish to all subscribers
If you want to publish a message to all clients subscribing to a topic, use PublishToAll
Server
//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;
this.PublishToAll("Hello to all subscribers from server", "chatmessage");
Client
Client - JavaScript
conn.controller('chat').subscribe('chatmessage', function(data){
console.log(data)
});
Client - C#
conn.Controller("chat").Subscribe<string>("chatmessage", data => Console.WriteLine(data));
How to publish to a subset of the subscribing clients
If you want to send a message to some of the subscribing clients, use PublishTo
This is where you will see the power of state! You will actually get intellisense so that you can write lambda expressions to target the subscribers you want to send the message to.
If we have the properties City and Gender on the Controller
(for example) we can target exactly the subscribers we want to, instead of all of them.
Below for example we send to all clients having the same gender and location as the caller
Server
//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;
this.PublishTo(p => p.Gender == this.Gender && p.City == this.City,"Hello to some from server", "chatmessage");
Client
Client - JavaScript
conn.controller('chat').subscribe('chatmessage', function(data){
console.log(data)
});
Client - C#
conn.Controller("chat").Subscribe<string>("chatmessage", data => Console.WriteLine(data));
How to publish messages to subscribers connected on another Controller class
It is pretty much the same as publishing to the clients on the same Controller
since XSockets extension-methods are generic.
So, if you are on Controller
A and want to publish to all chatmessage
subscribers on Controller
B you just use...
//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;
//To all
this.PublishToAll<B>("Hello to all 'chatmessage' subscribers on 'controller' B from server", "chatmessage");
//And the powerful `PublishTo<T>` would have a signature like:
this.PublishTo<T>(Func<T,bool> expression, object obj, string target);
How to call subscribers outside the Controller class
Just create a controller instance (or ask the plugin framework after the specific controller) and then use the extensions to send data
//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;
//Create the instance your self
var chat = new Chat();
//Then just use one of the extensions to target, one, some, others or all...
chat.PublishToAll<Chat>("Hello from manual instance","say");
Notice that you have to pass in <T>
in the extension regardless of what controller you want to use. So you can even do:
new Chat().PublishToAll<Stock>("Hello to stock clients from chat instance","hi");
Note: there is no point in using Invoke/Publish since the actual controller does not have a socket since there is no client connected to it (we created the instance manually).
GitHub Pub/Sub Sample
https://github.com/XSockets/XVA/tree/master/XVA-01-05-StatePubSub