WCF prevent server disconnect - c#

I have a small client/server application. I was using a hand-coded TCP connection to allow the client to control the server, but now I've converted it to WCF. This saved me a whole bunch of code, but it also gave me a whole new set of problems to fix...
The latest problem is that after a while, the server disconnects the client. I do not want this to ever happen, under any circumstances. Currently the client gets about a quarter of the way through its run, and then explodes with fire because the server has dropped the connection. I need to stop this happening.
I was able to write a trivial WCF client/server pair that replicates the problem. It seems that if the client calls a method, waits 15 minutes, and then calls a second method, the second call throws an exception babbling something about the socket having been closed. If I reduce the delay, everything works fine.
I read in another answer somewhere that setting ReceiveTimeout should fix this. However, when I tried it, this only fixes the problem under .NET; when running under Mono, it still breaks. Since Mono is the actual target platform, this isn't very helpful.
(Think about SSH - you would not want an SSH server to disconnect you just because you didn't type anything for a while. Perhaps you issued a long-running shell command or something... Just because the server hasn't received any data from you doesn't mean nothing is happening! It certainly doesn't mean your connection should get dropped...)
All code is C#. The server is a self-hosting console app. The client is also a console app. All configuration is in code. Binding is NetTcpBinding with default settings.
What can I do to allow the client to run to completion successfully?
I have a few ideas, but none of them are pretty:
Manually send heartbeat messages. (Yuck!)
Detect disconnection and automatically reconnect? (Again, yuck.)
Turn on "reliable mode". (I'm guessing that since the server deliberately ends the session, this won't help.)
Create one connection per method call. (That's going to be quite a lot of code...)
Stop using WCF?

In the end I "fixed" this by having the client make a new connection for every single command. This works acceptably because the client doesn't send commands all that often. It's annoying having to write the connect/disconnect code a dozen times though...

Related

Number of web socket clients that could be opened at once

I am simply looking at the sample code found here:
When I run the server portion and start multiple instances of the client I notice that when I start around 40-50 of them at the same time (using Process.Start()) that sometimes some clients fail to connect.
Why does this happen? What actually stops all these clients from connecting at once? Is there a request limit hidden somewhere?
Are you sure the limitation is not on the server?
I use ClientWebSocket to do some simplistic stress test on my WebSocket component and I can reach thousands or connections and almost a 100% throughput of my NIC. However, I do not create a process for each call. You can see the test console app source code or just download the executable here.

How to detect client's timeout exception on the server side?

I am using synchronous WCF service which works well 99% of the time, but on some very rare occasions client times out before the server finishes processing. Is there a way to detect, on the SERVER side, that the client has timed out? I could use async operation, but in this case server-side timeout detection would save me quite a lot of work. I'm using net.tcp binding, if this matters.
For net.tcp, http, etc. in general no. (see comments above for some ideas; also it might be different for other protocols/bindings/etc.)
The reason is, that the WCF infrastructure code on the server side will not use the channel before it has finished executing the service operation's implementation code and marshalling the response. Only then it will attempt to send the response and at this point recognize that the connection has already been aborted by the client.
When the server gets that error the user code (your service operation implementation) is already done and thus you cannot react to that from there anymore. It might be possible from within a dispatcher, or other extension point, but personally I have not tried. However, that also would not save your server from unnecessary work, because as said, the client disconnect will still only be recognized when the server actually attempts to send the answer.
One "simple" way to mitigate such issues might be to split the work being done into several service operations/calls (if at all possible; and not accidentally introducing server-side state in the process). Or as others have said, have the client implement a "Ping" interface that the server can use to check if the client is still "alive" and the response is still needed.

tcp client can't connect to local server randomly in unity

I have an unity3d client using BeginConnect to connect my local server, but the connection can not be established randomly, espacially after I restart the unity editor. Once it connected, it will become quite normal even I restart the game(not the editor) many times.
The wireshark shows that nothing are sent when issue occures.
I have another very similar client but it can connect to my another similar local server very perfectly.
Any idea what caused the problem?
Thanks in advance.
===
PS.
Even with a retry mechanism the client can connect to server succssfully but the later async operations(BeginSend & BeginReceive) may still randomly stop working.
The connect may be unresponsive even I ran the client without runing the server.
I have code to close the socket in the OnApplicationQuit() function:
socket.Shutdown(SocketShutdown.Both);
socket.Close();
Another similar client has almost the same codebase but works very well.
I found another similar issue: http://answers.unity3d.com/questions/925955/socketbeginwrite-no-response-in-463f1.html?sort=oldest. but it can't explain why my another client(same version of unity) works.
Most of our TCP related problems were related to failing to close the listener thread or failing to disconnect from server.
When you create a thread in editor environment, the thread will continue to exist as long as the editor runs, even if you stop the game. If you use TCP in a multithreaded way, you have to manually stop the thread in some OnDestroy or OnDisable methods.
Also make sure you disconnect from server when you stop the game.
If these were not enough to solve your problem, then I may be able to help if you can share some example code that causes this problem.
According to this http://answers.unity3d.com/questions/925955/socketbeginwrite-no-response-in-463f1.html?sort=oldest, it seems that in unity3d v4.6.3f1, the mono runtime has some bugs in the implementation of BeginXXX series functions.
The unity team may fixed these bugs in newer version(not tested), but I still need to stay on v4.6.3f1, so the workaround is replacing the BeginXXX with XXXAsync series. (tested and works for my problem)

Webservice for serial port devices

I want to create a remote webservice for an application that is now avaliable only localy. This application controlls three devices (each is controlled separately) connected on serial port. The problem is that I don't know how to take care of passing back information that a device return requested data. For example - I send move command to the motion device (which is very slow and can take a minute or more). Can I just set a big timeout on the client side (and server side) and return for example a true/false if operation is completed or is this a bad idea? Is SOAP with big timeouts ok?
And the other question is if Mono on Linux (Ubuntu 9.10, Mono 2.4) is stable enought for making a web service or should I chose Java or some other language?
I'm open for recommendations.
Thanks for your help!
Using big timeouts is not a good idea. It wastes resources on both the server and the client and you will not be able to detect a "true" timeout condition, when the server is unavailable for example, before the allocated timeout expires.
You really have two options. The first is to use polling. Return immediately from the motion request command, acknowledging the reception of the command (and not the completion of it). Then send requests in regular intervals, asking whether the command is completed or not.
The other alternative requires the client to be able to register a callback endpoint, which the server will call when the motion completes. This makes the whole process asynchronous, but requires the client to be able to operate in server mode. This is very easy to do with WCF - I don't know however if this functionality is available in Mono.
Not directly related to your question..., but consider com0com and its friends hub4com and com2tcp.

Client/Server connection woes

I've written a client/server model in C# using .Net remoting. If I have the client connected to the server, then kill the server and restart it without trying to call any server methods from the client whilst the server is down, I can reconnect happily.
If I close the server then try to ping the server from the client (which I do from a separate thread to avoid an endless wait) then when the server comes back online, the client can never talk to it and my Ping thread that was fired during the downtime waits forever deep in the guts of the remoting libraries. I try to Abort this (if trying to Join the thread fails after a short time) but it won't abort. I'm wondering if this is part of the problem.
If I start up another client, then that client can talk to the server just fine. I figured I needed to restart some aspect of the original client but cannot see what would need to be shut down. I certainly null the server I'm connected to and call Activator.GetObject with the same address (something the second client does to connect to the server, which works fine), but re-getting the server doesn't help at all.
The server is running a as singleton via RegisterWellKnownServiceType.
I would start with wireshark and use it to see what is really going across the wire.
Is .NET remoting a requirement, or could you consider moving to WCF instead? The protocols are better factored and more clearly exposed when needed.
I was solving a similar problem. I had a working .NET remoting application using configuration files for the remoting and the routines of the .NET remoting I had to integrate into a larger application. I integrated this into the larger project, by the Activator.GetObject returned an instance of the proxy. As soon as there was a call of a member from the proxy instance, it ended up inside the member call and could not get off. The larger application contained various configuration files already thus the .NET remoting configurations I placed right there along with another configs for another thihs, and there was the crux of the matter. After I placed the .NET remoting configurations into a new empty config(s) file, the .NET remoting in the larger application started to work.

Categories