I'm whiling to add a support of Server Side events to CppCMS. I understand the technical part of what to do on the
level of communication: Client sends long polling XmlHTTPRequest, and waits for respond,
server accepts the connection and does not respond until server side event occurs and sends
the response to the client. The client repeats the procedure.
However, this is too "low" level for most of web developers. There are many questions: how do I manage events, how do I manage connections and so on.
I thought about two possible models:
There are some named events defined and the server side,
for example "New Message in Chat Room no 134";
when the request accepted the server side application checks the messages
in the room (for example in DB) and if there is no new messages for the client
it subscribes to event and waits on it.
When some other client posts data to the server, it notifies all applications on
the "New Message in Chat Room no 134" event and they wake up and send these messages
to clients, and so on.
This model is still looks like quite "low level" model, but it hides all
notification methods.
Another option is to define some named queues, so each client creates such
queue upon connection to server and waits for new messages. When some client
posts a new message to "Chat Room no 134", on the server side it is broadcasted
to all queues connected to this "Chat Room no 134", and the message is delivered
to client.
However there are many questions that are risen:
How do I manage queues and the session level, at the level of single page?
How do I delete queues and create timeouts on them?
What happens if more then one "window" subscribes to same queue?
Create a persistent object on server side that glues between server side events
and user side events. It may communicate over distinct XHR requests that are
redirected to it.
So client (JavaScript) registers events and waits for them with XHR
and server side dispatched event notifications, until the page is rebuild.
So, I would like to know, what are most popular and recommended
API models behind server side push technologies?
Thanks
Edit: Added third option
You should check out XMPP PubSub, which defines a generic publish/subscribe protocol over XMPP. There's also an XMPP extension called BOSH (lower-level protocol details are documented separately in XEP-0124) that defines a mechanism that allows HTTP clients to bind to XMPP servers using long-polling (i.e., comet). Combining these two specifications gives you a robust event subscription model for web-apps using comet. Even if you don't end up using XMPP/BOSH, the specs contain some valuable insight into how this sort of system can be built.
If you do end up using XMPP and BOSH here are some tools you may find useful:
StropheJS: A library for writing client-side XMPP clients that speak BOSH.
Idavoll: A generic publish-subscribe service component for XMPP servers.
Punjab: A BOSH connection manager that acts as a sort of "translating proxy" between BOSH HTTP clients and your XMPP server.
Admittedly this is a very heavy-weight solution, and it may not be appropriate for your particular application, but a lot of thought was put into these standards so they may be helpful.
Try Bayeux, it's very much like your first model. The client subscribe to channel "chatroom/new-message/134". If there are new message, the server will broadcast to the subscribers.
You can use wildcard channel name to subscribe to multiple rooms "chatroom/new-message/*" (trailing only)
There's no general solution that fits all applications. If you want to learn about some general patterns, have a look at Event-Driven Architectures.
There are some slides online from a presentation I attended once (it's a quite high-level view of the topic).
Related
I am novice in WCF and I have a project that needs to be migrated into WCF communication base with the client/server and server to server architecture.
My question is what is the right messaging function that I need for this project that insure the security of data across the network ,reliable connection and speed exchange of data.
I was able to find out the WCF has numerous messaging function.
Below is the architecture of my project:
Note: The clients should be simultaneously updated by both data processing and feed source servers. And clients also sends simultaneous requests to the servers while feeds are still being supplied by the feed source server.
I would be appreciate any suggestion or comments.
My first question is why are you putting the Connection Manager (CM) component in-between your clients and the services which they want to use? What is the job it does which means it needs to be right in the middle of everything?
This ultimately means that your CM component will have to handle potentially high volumes of bi-directional traffic across potentially different transport bindings and introduces a single failure point.
What if client A wants only to receive messages from the Feed Source (FS) component? Why should client A have to deal with an intermediary when it just wants to send a subscription notification to receive updates from the FS?
Equally, what if client B wants to send a message to the Data Processing (DP) component? Surely it should just be able to fire off a message to DP?
I think the majority of what you want to do with this architecture can be achieved with one-way messaging, in which case you should use netMsmqBinding (assuming you are in a pure wcf environment).
The scenario is a follow:
I have multiple clients in which they can register themselves on a workflow server, using WCF requests, to receive some kind of notifications. The information of the notifications will be received from an external system using another receive activity. The workflow then should get the notification information and callback all registered clients using send activity and callback correlations (the clients are exposing callback interfaces implemented in there and the end-point addresses passed initially with the registration requests). "Log-running workflow service" approach is used with a persistent storage.
Now, I'm looking for some way to correlate the incoming information of the notifications received from the external system with the persisted workflow instances created previously when the registration requests, so that all clients will be notified using end-points that already passed with the registration requests. Is WF 4.0 capable of resuming and executing multiple workflow instances when the information of the notification received without storing end-points somehow manually and go though them? If yes, how can I do that?
Also, if my approach of doing so is not correct, then please advice me about the best practice of doing such system using WCF services.
Your help is highly appreciated.
When you use request correlation with workflow services the correlation key must always match a single workflow instance, you can't have multiple workflow instances react to a single message. So you either need to multicast the message using all the different correlation keys or resume you workflow instances in some other way. That other way could be to store the request somewhere, like a SQL table, and have the workflows periodically check that location if they need to notify the client.
I have a project coming up where I need to send and receive messages through a specific mobile operator, which only provides an SMPP interface. The whole project will be a hosted website. I have already read quite a lot, but I do not yet quite understand what is actually needed from my side to use the protocol.
Should my application try to maintain a constant connection to the smpp?
Can I simply connect, send a message and then disconnect?
Are receiving messages based on push or pull?
Thanks for the help.
SMPP is a peer-to-peer protocol. That should mean that SMS Gateway (your side) and SMSC (your mobile operator) need to have a proper bind/connection established. Even when there are no SMS or DLRs to send/receive, there is a continous exchange of smpp PDU (enquire_link/enquire-link_resp) that ensure that the bind is established.
In detail, if you send an enquire_link PDU and you get no response (enquire_link_resp) the bind is broken. Your sms won't be delivered (will remain enqueued in your gateway store), and you won't receive MOs (incoming sms) or DLRs (delivery report). To re-establish the connection you should re-initiate the connection.
So, my answer would be that you need a constant connection to SMSC.
You are stating you want to receive messages, as a result at least a bind_receiver is needed. Because you don't know when messages are going to come in, you will have to be constantly connected, rather than disconnecting after each event.
With regards to your question about "push or pull" this depends on how you solve the first problem. If you can build a solution that is constantly connected, the result will be a push (the carrier will push it to you as soon as they receive the message). If (for some reason) you cannot maintain a constant connection, you'll end up building a pull mechanism. You'll connect to the carrier ever X seconds to see if they have a message waiting for you.
I do need to highlight 2 pitfalls though:
A number of carriers in the world, do not store or even accept messages if you are not connected, therefore, depending on which carrier you interact with, you might be forced to use a continuous connection.
Most carriers do not allow you to open and close connections in quick succession. Once you disconnect, you can not reconnect for a time frame of X seconds.
Therefore a constant connection is really the way to go. Alternatively, you can look into a company like Nexmo, which will provide you with a HTTP Call every time a message arrives.
I'm not sure which language your developing your application in, but if you use any of the popular languages (Java, PHP, Perl) there are modules out there that handle basic SMPP Connectivity for you. A quick google search for your language and "SMPP Client" will give you a list of references.
Using techniques as hinted at in:
http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.callbackcontract.aspx
I am implementing a ServerPush setup for my API to get realtime notifications from a server of events (no polling). Basically, the Server has a RegisterMe() and UnregisterMe() method and the client has a callback method called Announcement(string message) that, through the CallbackContract mechanisms in WCF, the server can call. This seems to work well.
Unfortunately, in this setup, if the Server were to crash or is otherwise unavailable, the Client won't know since it is only listening for messages. Silence on the line could mean no Announcements or it could mean that the server is not available.
Since my goal is to reduce polling rather than immediacy, I don't mind adding a void Ping() method on the Server alongside RegisterMe() and UnregisterMe() that merely exists to test connectivity of to the server. Periodically testing this method would, I believe, ensure that we're still connected (and also that no Announcements have been dropped by the transport, since this is TCP)
But is the Ping() method necessary or is this connectivity test otherwise available as part of WCF by default - like serverProxy.IsStillConnected() or something. As I understand it, the channel's State would only return Faulted or Closed AFTER a failed Ping(), but not instead of it.
2) From a broader perspective, is this callback approach solid? This is not for http or ajax - the number of connected clients will be few (tens of clients, max). Are there serious problems with this approach? As this seems to be a mild risk, how can I limit a slow/malicious client from blocking the server by not processing it's callback queue fast enough? Is there a kind of timeout specific to the callback that I can set without affecting other operations?
Your approach sounds reasonable, here are some links that may or may not help (they are not quite exactly related):
Detecting Client Death in WCF Duplex Contracts
http://tomasz.janczuk.org/2009/08/performance-of-http-polling-duplex.html
Having some health check built into your application protocol makes sense.
If you are worried about malicious clients, then add authorization.
The second link I shared above has a sample pub/sub server, you might be able to use this code. A couple things to watch out for -- consider pushing notifications via async calls or on a separate thread. And set the sendTimeout on the tcp binding.
HTH
I wrote a WCF application and encountered a similar problem. My server checked clients had not 'plug pulled' by periodically sending a ping to them. The actual send method (it was asynchronous being a server) had a timeout of 30 seconds. The client simply checked it received the data every 30 seconds, while the server would catch an exception if the timeout was reached.
Authorisation was required to connect to the server (by using the built-in feature of WCF that force the connecting person to call a particular method first) so from a malicious client perspective you could easily add code to check and ban their account if they do something suspicious, while disconnecting users who do not authenticate.
As the server I wrote was asynchronous, there wasn't any way to really block it. I guess that addresses your last point, as the asynchronous send method fires off the ping (and any other sending of data) and returns immediately. In the SendEnd method it would catch the timeout exception (sometimes multiple for the client) and disconnect them, without any blocking or freezing of the server.
Hope that helps.
You could use a publisher / subscriber service similar to the one suggested by Juval:
http://msdn.microsoft.com/en-us/magazine/cc163537.aspx
This would allow you to persist the subscribers if losing the server is a typical scenario. The publish method in this example also calls each subscribers on a separate thread, so a few dead subscribers will not block others...
I want to use WCF to enable two way communication without opening a port on the client.
I'm developing something like a P2P application (similar to teamviewer/logmein) where you don't need to open ports to communicate.
How do I accomplish two way communication through HTTP/HTTPS without the need to open a port in the client?
Note : Port 80 can be opened in the server...no issues on that.
Thanks
Well those systems you mention work as follows. They first try to make client A and client B communicate directly via a range of different topologies which basically require one of them to allow incoming connections if that fails they fall back on a third party which acts as a man in the middle. So client A talks to the server and sends it messages for client B. Then Client A gets the messages addressed to it back in response. Client B sends it messages to the server and it's gets the message from client A back from the server. This way both client A and B always initiate the connection and don't need to have a port open for incoming traffic.
If I understand correctly in your case you would always want the man in the middle. In order to do this you would have to write a WCF service that provides all relevant methods. For instance things like
void SendMessageToClient(Guid senderId, Guid recipientId, Message msg)
Message[] GetMessages(Guid recipientId)
then have those methods respectively store and retrieve those Message objects from somewhere (like a database or a queue or something).
Then write a client that connects to the WCF service using the HTTP binding and call the methods on the server and process the results.
I hope you understand that
a) this isn't a very efficient way to communicate.
b) that it's difficult to test and debug and understand whats going on since there are so many parties involved and communication is asynchronous living in 3 different processes.
c) it adds an extra layer ontop of the communication so you need to keep it clear for yourself in your head (and prefereably in code) when you are dealing with the infrastructure bits and when you are dealing with the actual protocol clientA and clientB speak to each other in the Message objects.
Pseudo (code) Example
in this example I assume the message object is nothing more then a string and the only command is "whattimeisit" to which the response is the local time in string form
ClientA makes call to server.SendMessageToClient("clientA", "clientB", "whattimeisit");
Server stores this message in the database with ID 1
ClientB makes call to server GetMessages("clientB");
Server retrieves message with ID 1
ClientB recieves back "whattimeisit" as a response
ClientB makes call to server.SendMessageToClient("clientB", "clientA", "19:50:12");
Server stores this message in the database with ID 2
ClientA makes call to server GetMessages("clientA");
Server retrieves message with ID 2
ClientA recieves back "19:50:12" as a response
I'm not sure I understand. The purpose of digital firewalls is (generally) control communication channels. If you want to communicate bypassing firewalls you have two choices.
Hide the message in something the firewall lets through
Use a communications channel the firewall doesn't control
In the case of the earlier:
You could pass messages to proxy that passed them on (email is a good but not exactly responsive example).
In the case of the latter:
You could put the messages on say file where some other transport layer carries them