views:

597

answers:

5

In my WCF service, when trying transfer large data I constantly get an error: *The underlying connection was closed: The connection was closed unexpectedly*

I want to know what particular reason invokes this error, so I set up WCF Tracing and can read traces.svclog file.

The problem is, that I can see in this file a lot of information about flow of processes, I can see exact time when exception is appeared, but I can't see the exact reason for that. Is it due to *MaxReceivedMessageSize* or something like that.

Is it so that traces.svclog can not contain such information or am I doing something wrong?

How such information could be obtained?

Edited (added):

From my server-side app.config:

    <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="NAVBinding_ICustomer_Service"
                closeTimeout="01:50:00"
                openTimeout="01:50:00" receiveTimeout="01:50:00" sendTimeout="01:50:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
                maxReceivedMessageSize="2147483647" messageEncoding="Text"
                textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service name = "Customer_Service"  behaviorConfiguration="returnFaults">
            <endpoint name="NAVBinding_ICustomer_Service"
               address  = "http://localhost:8000/nav/customer"
               binding  = "basicHttpBinding"
               bindingConfiguration= "NAVBinding_ICustomer_Service"
               contract = "NAVServiceReference.ICustomer_Service"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="returnFaults" >
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceMetadata httpGetEnabled="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
 </system.serviceModel>

Edited (added):

What is the right and best way to turn WCF service from a "black box" to an easily troubleshooted service, which tells the reason why something goes not the expected way? What tools, techniques you use to troubleshoot WCF service?

A: 

You should get a specific communication exception on the client side. I think that this exception that you're describing is an exception that is thrown after trying to reuse the client after it has faulted.

Try this:

  1. On the server side config file set includeExceptionDetailInFaults="true"
  2. When you're using the client side don't use the 'using pattern'. Check out this article.

I don't think you need tracing. Try the above and you'll be able to see the exact communication error.

Oh, and BTW is your client is Silverlight application? If so then it's a bit more complicated... Check out this article.

Yuval Peled
No, it isn't Silverlight, it is WPF app
rem
In fact, I have includeExceptionDetailInFaults="true" included in my server app.config file, but it doesn't help to get reasons of disconnections. Maybe I set it incorrect.
rem
+1  A: 

Try setting the maxRequestLength property:

<system.web>
    <httpRuntime maxRequestLength="2147483647" />
</system.web>
Darin Dimitrov
I have tried (simply added your code to server app.config), but there are no visible changes in what happens.
rem
Is there any chance you could upload somewhere the `traces.svclog` file so that we can take a look?
Darin Dimitrov
Yes, of course. Here it is: http://bit.ly/5Dcj4I
rem
+3  A: 

Ignoring the problems with the maxRequestLength (which have been answered by others), I will have a go at answering your original question about how to troubleshoot WCF.

If you are already using the Service Trace Viewer (I couldn't tell from the question if you were just viewing them by hand) - it is possible that all the details aren't going into the file.

When I want to get really hardcore, I enable all the logging parameters for message logging. (This will generate some big service logs though so don't leave it on)

 <system.serviceModel>
  <diagnostics>
   <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="-1" />
  </diagnostics>
 </system.serviceModel>

If you are not using the Microsoft Service Trace Viewer I recommend that. It gives all the information I need to track down those tricky message handshake, message size exceptions etc. Here is an MSDN reference to get you started http://msdn.microsoft.com/en-us/library/aa751795.aspx

Trace interactions that have potential problems are hilighted in yellow on the left, and the detailed pane on the top right will normally hilight the exceptional service event in red. Sometimes you will get multiple problems as the inner error cascades through the service stack - but you can see it all in the trace viewer.

alt text

If you get nothing in your server 'service log', then it is possible your exceptions are entirely at the client end - theoretically you could exceed some of the client side security parameters (message size etc) before any message has actually reached the web service end - but client problems are generally easier to track down because you know you only have to worry about editing the config file at the client end (i.e. it's not because of any interaction between the client and server settings).

Andrew Patterson
+1 for the screenshot and reference to the Service Trace Viewer, which basically rocks.
Jeremy McGee
A: 

To answer your question how to create an easily trouble shooted WCF service. One way is to minimise the number of potential errors, so that you have fewer things to look at while troubleshooting.

There are two main sources of errors:

  • An error due to the configuration
  • An exception thrown by the WCF service

Errors in configuration are often due to a mismatch between the client and the service. To avoid this place all configuration possible in a BindingConfiguration and copy and use this on both the client and the server. This I think is actually where your problem is, you are updating the service web.config, with things that also need to be in the client config. For eaxmple the max size, or having Buffered in one and Streamed in the other.

Errors throw by the service should be thrown as a FaultException and defined in the Contract as a FaultContract.

For remaining errors you need to look at the trace.svclog file as described in other posts. You need also to look at the event log and IIS log, the calls may be blocked before they reach the WCF service.

Shiraz Bhaiji
+1  A: 

I've spent the last 2+ days trying to find why I'm getting "The underlying connection was closed: The connection was closed unexpectedly" with a method call returning with more data vs when not so much data (i.e., it works ok with smaller sets of data being returned only).

My error messsages are slightly different (perhaps due to framework differences) but wanted to share the cause I found. First, I would like to state that while tracing and increasing the sizes of certain things in config files given as answers above may be helpful for tracking down WCF errors, these things did nothing to help me determine the real cause of the error.

By just looking at the exception thrown and up the chain, I could see the following root, error: "An existing connection was forcibly closed by the remote host" - this was a System.Net.Sockets.SocketException

Going up the call chain then was: "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host." - a System.IO.IOException, then

"The underlying connection was closed: An unexpected error occurred on a receive." - a System.Net.WebException, then finally what was the caught exception's message,

"An error occurred while receiving the HTTP response to . This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details." - a System.ServiceModel.CommunicationException

The enabling tracing then viewing the trace logs with the TraceViewer did make this easier to see, but never told me the real cause for my "An existing connection was forcibly closed by the remote host" error.

In my case, my WCF service is hosted on IIS6 and only when I contacted our institutional support in charge of these servers and asked them to look in the system event logs, did I immediately see the answer - a System.OutOfMemoryException!

My WCF service runs in an allocated 200MB of RAM and my method was consuming more than this. I looked in my method and found eventually a block of code that should have been outside/below the block (loop) it was in. . ..so I had an exponential type of collection being generated in my method.

Hope this may help others.

Kent Kruckeberg
Thanks for sharing experience, +1. And welcome to SO!
rem