I'm trying to figure out if PollingDuplex is the right way to go for my problem.
Here is my scenario:
1. 3rd party application sends a UDP packet with a client's IP address to a server app.
2. The server app needs to the notify the specified client and send along some data.
The client is a Silverlight application.
I've been looking at some guides and sample code (http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture/) but I don't understand how clients are identified on the server using PollingDuplex. I understand that the clients register with the server and continually poll for messages. How would I make sure that only the right clients get the message designated for that client? In other words, the messages on the server should not be broadcasted to all polling clients but only sent to one specific client.
Any help is much appreciated.
Whether you're using Net.TCP or HttpDuplexBinding, clients can be identified using OperationContext.Current.Channel.SessionId. And more specifically, you can grab the actual channel that WCF uses to talk to them using OperationContext.Current.GetCallbackChannel<IMyCustomServiceInterface>(). You can store those in memory, perhaps associated with some other identifier passed up from the client, and when you need to communicate with the client in question (e.g., to pass them the data from the UDP packet), you call the appropriate method on that specific stored channel; and the client will get notified.
I should note that while I don't particularly recommend HttpDuplexBinding, apart from its quirks and stability and performance issues, it should work for what you're doing, and in exactly the same way as Net.TCP. Although the clients technically do "poll" the server, that's hidden from you. All you know on the server is that you're calling a method on a particular channel. The underlying binding code takes care of making sure that the right client gets notified.
Polling duplex is actually an entirely client side implementation that exists only for Silverlight (there's no regular .NET framework version of it, except a project on Codeplex Microsoft's own internal consulting services developed for a high profile client of theirs). There's nothing at all special about it on the server side.
It's not really meant to be used in production by Microsoft's own admission (we have a Microsoft contact at our company who admitted this to us candidly). It's not very robust or well implemented and can/will DoS your server under any kind of volume:
http://forums.silverlight.net/p/89970/239380.aspx
You're better off rolling your own client side polling mechanism - or (better and more scalable) using TCP with session in Silverlight 4, which provides true duplex support (because the connection is not stateless and thus supports true push notifications):
http://www.silverlightshow.net/items/WCF-NET.TCP-Protocol-in-Silverlight-4.aspx.
Related
I'm currently trying to wrap my head around outbound transfer as a project of mine makes it a concern.
I discovered that if I try to play music directly off of my server, it counts towards my outbound transfer. This is understandable and I can understand the logic of that.
The idea I have is if I happen to host the file elsewhere, would the outbound transfer be counted towards my initial server, my 3rd party server, or both? I'm considering putting the music on dropbox for example and stream it from there through the server.
Is what I want even possible?
"outbound transfer" in this case most likely refers to the amount of bytes sent from that server. If you proxy the 3rd party server, you still send that data through your own server, so it won't net you any benefit, other than storage space. In fact, the latency will probably increase.
What you want to do is of course possible if you let the client connect directly to the streaming service. Just make sure that service allows you to stream data that way through their TOS. Also make sure that the service is actually designed for live streaming of data, or your user experience will be horrible.
we want to build an application (c#/.Net) for the following Scenario:
internal "alert System". Users should be informed about it-system outage, planned downtime for Services and so on.
only one-way : central Service will push Messages to user
we also Need the possibility to enable/disable a message, for example:
The message "there a Problems with mail System" should be removed from every Computer after the Problem is solved
we want to shedule Messages for planned maintanance
about 1000 windows Clients, we also want to "group" this Clients, so we can control which Client will get a message
First thought was writing small application which will query every X seconds a central database for new and existing Messages.
Maybe somebody has already worked on similar Project?
Is a Client with database query a way to go? Better to use other Technology, like WCF Service?
Thanks for your help
Marc
Sounds like you need an enhanced version of push notifications.
I'd suggest using push for all the messaging, it's delivered faster and I find it more reliable. Simply make the client connect to a message server and maintain the connection open. Whenever a message is supposed to be displayed to the client, have the server push it trough the connection (that's where the name comes from).
To group and manage the clients you could use a database, it's probably the best way to go, but the server needs to handle all the open connections, and databases can only store DATA, not virtual objects representing a connection, so the server software need to manage them in a different way.
My suggestion: Whenever the server receives an incoming client connection, it will accept and query the client computer for a ID number that will also be used to find that client's information in the database.
Then it will create a dictionary using that ID as key, and the connection as the value.
This way at the time of sending a message to a determined group, you can do in two ways:
1) You can load from the database the IDs that belong to that group, and then send the messages to them. You will have to check whether that ID exists in the dictionary's KEYS array, because it is possible that a determined client is not yet connected.
2) You can iterate of the KEYS array of dictionary, check to which group that ID is part of, and if it is the desires group, send it.
If you're dealing with a big number of clients, I suggest you use method 1.
To disable/remove a message from the client's computer, simply have the server send a special Command message that the client software interprets as "remove that message". To make this possible every non-command message must have unique IDs, so that command messages can tell the client software which message that command applies to.
Your project sounds very interesting.
I would be glad to help you by writing a library you could use, or just help you figure it out on your own if you prefer. (Free of charge, just for the experience).
I have read several similar topics on stackoverflow in which fellow programmers discourage the practice of using simple client/server applications and raw TCP sockets for communication. I acknowledge that there are concerns but for what I'm trying to accomplish I don't see any other reasonable way.
Here is what I'm planning:
I have a simple working prototype client/server that I wrote in C. The client application sends a request to my server to remotely execute code, generates a value and then relays this value to the client. The transmitted data is not sensitive, will only be held in RAM and will be rejected if it exceeds a predefined length. If I run a (hardened) dedicated server with the sole purpose of remote code execution to generate a response are there any security issues I'm overlooking?
I am less worried about my server being compromised and more worried about possible harm to client computers. I'm not blind to the potential that my server gets hacked - I'm just trying to convey that their won't be any sensitive data on it even if it does get compromised. I don't see how anything malicious could be injected (mitm) given the narrow scope of the data being transmitted but maybe I'm naive and overlooking something? Please let me know.
I could accomplish this over HTTP with a re-write trick but that is convoluted, I'll incur more overhead than I want and I'm unsure it would be any safer.
Thanks.
You need to think about the possibilty of your server being damaged or wiped or even powered off by an intruder. Anything involving remote execution of code rings my alarms. You must at least use a secure client authentication scheme.
Confidentiality - not needed if you feel data is not sensitive
authentication - certificates can be used to make sure client talks to real server. Pls check openssl
Make sure the server is running with reduced privilege rather than root so that server can't be compromised completely in case of memory corruption attacks.
Using HTTP won't make any difference, HTTP uses TCP connections at transport layer.
HTTPS would be a possible solution.
I would like to implement a chat system as part of a game I am developing on App Engine. To implement this, I would like to use WebSockets, and have clients connect to each other though a hub, in this case an instance of GCE. Assuming this game needed to scale to multiple instances on GCE, how would this work? If I had a client 1, and the load balancer directed that request of client 1 to instance A, and another client (2) came in and was directed to instance B, but those clients wanted to chat with each other, they would each be connected to different hubs, and would be unable to reach each other. How would this be set up to work with scale? Would I implement it using queues, where each instance listens on that queue, and if so, how would I do that?
Google Play Game Services offers exactly the functionality that you want but in regard to Android and ios clients. So this option may not be compatible with your game tech design.
In general you're reasoning correctly. Messages from client who want to talk to each other will most of the time hit different server instances. What you want to do is to make instances handle the communication between users. Pub/sub (publish-subscribe pattern) is very suitable pattern in this scenario. Roughly:
whenever there's a message directed to client X a message is published on the channel X,
whenever client X creates a session, instance handling it subscribes to channel X.
You can use one of many existing solutions for starters. It's very easy to set this up using redis. If you need something more low-level and more flexible check out zeromq.
You can expect single instance of either solution to be able to handle thousands of QPS.
Unfortunately I don't have any experience with scaling neither of these solutions so can't offer you any practical advice as to the limits of their scalability.
PS. There are also other topics you may want to explore such as: message persistence and failure recovery I didn't address here at all.
I didn't try to implement this yet but I'll probably have to soon, I think it should be fairly simple to handle it yourself.
You have: server 1 with list of clients and you have server 2 with another list of clients,
so if client wants to send data to another client which might be on server 2, you have to:
Lookup if the receiver is on current server - if it is, you just send it (standard)
Otherwise you send the same data to all other servers you have, so they would check their lists for particular client (or clients) and send data to them.
This is more out of curiosity and "for future reference" than anything, but how is Comet implemented on the database-side? I know most implementations use long-lived HTTP requests to "wait" until data is available, but how is this done on the server-side? How does the web server know when new data is available? Does it constantly poll the database?
What DB are you using? If it supports triggers, which many RDBMSs do in some shape or form, then you could have the trigger fire an event that actually tells the HTTP request to send out the appropriate response.
Triggers remove the need to poll... polling is generally not the best idea.
PostgreSQL seems to have pretty good support (even PL/Python).
this is very much application dependent. The most likely implementation is some sort of messaging system.
Most likely, your server side code will consist of quite a few parts:
a few app servers that hansle incoming requests,
a (separate) comet server that deals with all the open connections to clients,
the database, and
some sort of messaging infrastructure
the last one, the messaging infrastructure is really the key. This provides a way for the app servers to talk to the comet server. So when a request comes in the app server will put a message into the message queue telling the comet server to notify the correct client(s)
How messaging is implemented is, again, very much application dependent. A very simple implementation would just use a database table called messages and poll that.
But depending on the stack you plan on using there should be more sphisticated tools available.
In Rails I'm using Juggernaut which simply listens on some network port. Whenever there is data to send the Rails Application server opens a connection to this juggernaut push server and tells it what to send to the clients.