IRC protocol - constant client connections ok? - c#

When I was experimenting with C# and WCF one of the things I kept reading about was how unscalable it is to have clients with a constant current connection to the server. And although WCF allows that it seems that the recommended best practise is to use 'per call' as opposed to 'per session' for instance management if you want to have any kind of decent scalablity. (Please correct me if Im wrong)
However from what I understand IRC uses constant client connections to the server and IRC servers (well networks of servers) are servicing hundreds of thousands of clients at any given time. So in that case is there nothing actually 'bad' about keeping constant client connections to the server?

As long as you don't follow the one-thread-per-connection architecture, a server can support quite a large number of concurrent TCP connections.
IRC doesn't require much per connection state, beyond the TCP send and receive windows.

If you need real-time duplex communication (IRC is a chat protocol), then keeping a TCP connection alive is a relevant option. However, TCP connection brings network overhead and operating systems have practical limits on the number of concurrent open TCP connections. WCF is commonly used in SOAP/HTTP/RPC contexts where duplex communication is not required, but certainly it offers suitable bindings and channels for that as well. To answer your question, there is nothing bad in keeping the connection open if you have real-time, duplex requirements for your communication.

Yes, such architecture is feasible, but... The "ping? pong!" thing was invented for a reason - to let both parties know that the other party is still there. You cannot actually tell if a client is idle, because it does not have much to say or because it is actually disconnected and you are waiting for a TCP timeout.
UPD: "hundreds of thousands of clients" is possible on IRCnet only because of server networks. For a single machine, the C10K problem is still an issue.

Related

Safely Creating "Heart Beat" over Network (Ping?)

I created extended TCP server and TCP client classes (in C#) for communication over network for my project use.
And as far as I understand, a client cannot really know if a server is down unless it requests for something which expects a reply but does not get it.
In our application, time and availability (of the server) are critical factors as it involve heavy machines for automation. Hence, according to the discussion on the design, the server is supposed to send its "Heart Beat" periodically such that in case a client does not receive anything from server after a period of time, it will:
Start to attempt its own recovery actions and if it still fails,
It will raise alarm to the service officer in the control room
I am supposed to implement the "heart beat" part in the server. And I have simple implementation of creating "Heart Beat".
public void SendHeartBeatToAllClients(byte[] hbdata) {
foreach (Socket socket in clientNoSocketList.Select(x => x.Value).ToList())
socket.Send(hbdata);
}
So far it works fine, but one thing that worries me is that the heart beat data (hbdata) is short (only few pre-arranged bytes, to save time to talk over many machines) and self-defined and since the server also sends some other data besides the hbdata, and considering the possible latency or other unexpected case, there is always a possibility for this hbdata to be mixed up. Also, in my "heart beat" implementation, the client does not need reply anything to the server.
So here are my questions:
Is my worry not well-grounded (as it is fine so far)? Is there any flaw?
Is Ping a better or a common way to have such heart beat functionality over TCP? Why or why not?
If Ping is to be implemented, considering that Ping has reply, is there a way to implement replyless Ping?
Any suggestion to make the heart beat robust enough yet in the shortest amount of data possible?
This is probably the hardest question to answer. Can you provide a little more detail? Why do you think that your server can't handle sending more than a few bytes? Are we talking thousands of machines here? Is everything on a local LAN, or does this go across multiple networks, or the internet?
Ping is an ICMP echo request - ping is very commonly used by networking monitor software, etc to ensure that clients are online. Typically you do not need to implement your own, if you are just pinging for network access (see: https://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping(v=vs.110).aspx).
Also note that ping is not over TCP at all, but rather ICMP, a somewhat different protocol, used for network diagnostics among other things. But that brings me to number 3...
Ping without a reply is kind of pointless. For what you have in mind, I think the protocol you want is UDP - you can broadcast an arbitrary datagram, with no need for any kind of handshake or reply (TCP by definition involves establishing a session with a handshake) - it just sends. These would be Sockets with SocketType.Dgram instead of SocketType.Stream, and ProtocolType.Udp instead of Tcp or ICMP. If you want to get a little more involved, you can use Broadcast to send to same thing to the entire LAN, or Multicast to send to a specific group of clients.
Again, are you sure you need to be that concerned about limiting traffic, etc here?
Personally, I would flip it around, and have the clients "Check In" at a set interval, reporting a status code to the server. If the server notices a client hasn't checked in for a while, it should send a message to the client and expect a reply.
If you really are having issues scaling that up, I would have the server send the "Heart beats" via UDP at a set interval, and if the client thinks it's missing them, have a mechanism for it to hit the server and ask for a reply - and then if it doesn't get a response, raise the alarm.
Edit: just saw Prabhu's answer - he's right, ping will only tell you if the computer is up, you definitely want something inside the actual application to report back, not just the status of the network connection.
in my "heart beat" implementation, the client does not need reply anything to the server.
Application level keep-alives need to be two-way is'n't? What the above enables is that clients can be sure that server is alive and healthy on receiving the heart beat. If the client does not respond, server will not know the true status of the client. If client becomes unreachable,heart beats pile up in the servers send buffer. Server application will be oblivious to the fact.
Is my worry not well-grounded (as it is fine so far)? Is there any flaw?
Small sized bytes shouldn't be a problem. Its better the heart beats are small.
Is Ping a better or a common way to have such heart beat functionality over TCP? Why or why not?
Ping will be positive even if the client application is down but the system is healthy.

Prioritized socket communication

I have a client-server communication between a mobile and a PC(server).
In the communication I have four sockets: two of these are to send and receive data, and the other two are for some kind of keep-alive, since I need to detect disconnections as fast as I can.
As long as the connection is OK, the data will travel without any problem. But I want to establish some priority in order to be sure that the keep alive (remember: two sockets) channel is always sending data, unless the connection between server-client is dead.
How can I achieve this?
Thanks for any help.
I would question your setup with four sockets.
First, having separate connection for discovering when remote end dies does not give you any advantage, but in fact introduces a race condition when that "keep-alive" connection goes down but "data" connection is still intact. Implement periodic heartbeats over same data connection when there's no activity.
Then two independent data connections between same nodes compete for bandwidth. Network stacks usually don't optimize across connection boundaries, so you get twice TCP overhead for no gain. Implement data exchange over the same TCP connection - you'll get better throughput (maybe at the expense of small latency increase, but only good measurement would tell that).
Last, but not least, four connections require four listening TCP ports, thus potentially four holes in a firewall somewhere. Reduce that to a single port, and administrator of that firewall will forever be your friend.
When using TCP for transmission your TCP protocol stack will inform you whenever you try to send data and the (TCP) connection is broken. If you control both server and client code you may well implement your heartbeat in between your data transmission over TCP.
If TCP's connection failure detection on the respective devices is too slow for your purpose you can implement some single packet ping-pong scheme between client and server, like the "SNMP echo request" a.k.a. "ping" - or if SNMP is not an option, maybe sending UDP packets back and forth will do the trick.
In any case you will need some kind of timeout mechanism (which is already implemented in the TCP stack), which implies that the detection of a broken connection will be delayed with the delay time bounded by the timeout duration.

can I switch from asychronous sockets to sslstreams without performance loss?

My question is in regards to the number of persistent connections. (Obviously there will be performance loss when adding SSL Encryption).
Currently I have C# server and client applications that use the Asynchronous Socket model http://msdn.microsoft.com/en-us/library/w89fhyex.aspx. I choose this model because it seems best suited to performance and the server application must support 5000 persistent socket connections.
I am at the point where I must secure the data being sent, and I am hoping to use SSL. Would I be able to change to SSLStreams and still support 5000 persistent connections? (I noticed that SSLStreams have asynchronous methods... Also, the reading I have done indicates that a stream is different but the same as a socket...)
One caveat is that the Server does not only communicate with other C# devices, it also talks to iOS, and Android.
Is there anyway to layer SSL on top of the Asynchronous Socket model?
If you can use third-party components, then SSL components of our SecureBlackbox product fit your task perfectly: they provide SSL layer which can be plugged to absolutely any transport, be it synchronous or asynchronous socket or even pigeon mail. And overall feature list is much wider than of built-in SSL.

Real time communication

I have the same dilemma as the one who posted this topic, Real-time communication with WCF
except that my problem is not about games programming. I would like to know what's the best method to use to be able to have a real time communication in between two windows applications (server-client). I am using visual c++/c# to date and i would like to be able to display all the Feeds that are being received by my server to the client in real time.
I have started trying to use .NET remoting but in my continuous research, it appears that it will use SOAP-http, and might affect the speed of the communication. My server and client will communicate using the internet and .NET remoting does not permit the use of TCP Channel when communicating in between a firewall or the internet.
Your inputs will be greatly appreciated.
I guess it depends on your escenario, if you want "real-time" and you are willing to lose some packages in the process you are better with UDP, take a video conferencing tool for example, by the time you recover your slow packages you will have to move and display the next frame in the video or audio; that is a good example for the use of UDP. This is the reason why UDP is much faster than TCP.
If however, you are not willing to lose a single bit of your message, then TCP was made for you because if you lost a package the protocol will request it again to have your complete message as complete as possible.
Additionally it depends on the way the communication is being sustained, is the information flowing from one to many?, from many to many?, one to tone?
Take NetNamedPipeBinding for instance, this will be much faster process, but is only deployed in a single machine but accross processes. Whereas NetMsmqBinding will help you to build queues and it will be amazingly reliable and scalable for scenarios where your load will be a massive number of connections.
In the end, it all boils down to your concrete escenario and your business goals.
Hope it helps
If you are willing to do your own message parsing, you can use standard TCP sockets with the TcpClient and TcpListener classes. If your data is already a serializable object, you could serialize it into a text stream and just send it over the socket, deserializing it on the client side.
To get it to work over the internet, the server needs to have the port forwarded on your router, the client would just attach to the server's public IP. You would obviously need to add an exception in your firewall for this port as well.
The biggest problem with WCF and large data is setting up the streaming, by default WCF sends everything at once, which isn't practical for large files.

Permanent TCP connection or connection etablishment at request processing

I am developing a TCP server, which shall communicate with the client, if specified tasks are finished. So I open on the server a socket and the client connects on it.
That connection can be used for data tranfers back to the client, too. That is quite okay.
But what about connection aborts and anything like that?
My thought was to connect each time to the server, when the client have to communicate with it. But how can I send data back to the client?
Shall I open a socket on the client side, too?
EDIT:
I have considered WCF, too. I think it could be a very good way to implements server client hierarchy.
What do you think?
It depends on the rest of your requirements. If we're talking a message that is in no rush that might be sent once a day, the right solution might be for the client to connect to the server periodically and check if there are any messages. If we're talking something that's more common and more in a rush, the right solution might be for the client to keep a connection open to the server at all times. In some cases, the right solution might be for the server to make a 'backwards' connection to the client, if possible -- perhaps with an option to fall back to a persistent connection from the client to the server if the 'backwards' connection isn't possible.
See this article on Push technology, particularly the section on long polling.
From a runtime POV having the server connect to the client needs a network environment supporting this (firewall/IDS etc.).
IF you can't be sure that this is always the case then this option is ruled out IMO.
As for the client keeping the connection open:
I think this is a good option... you need to make sure that the client implementation detects any connection problems and automatically reconnects...
Whatever solution you implement you might need to implement a queue of events per client... depending on your requeirements these queues might even need to be persistent...
WCF can work in all the ways I described and offers several things (like serialization, optional session management, transport security etc.) which help build a robust and well-maintainable system... although a pure TCP/IP-based solution might be better performance-wise...

Categories