views:

319

answers:

2

I'm getting a very unhelpful CommunicationException when attempting to call a WCF service from Silverlight 3. The message of the exception is "The remote server returned an error: NotFound." Each inner exception parrots that same message. Is there a problem with my setup that could be causing this issue?

Here's my setup. The WCF service is hosted in a Windows service running on the .NET 4.0 platform. It has three endpoints:

  • The main endpoint uses a pollingDuplexHttpBinding binding and has the address "DashboardService"
  • The metadata exchange endpoint uses a mexHttpBinding binding and has the address "mex"
  • The policy providing endpoint (this needs to allow cross-domain calls) uses a webHttpBinding binding and has the address "".

Here's the whole system.serviceModel section:

<system.serviceModel>
    <extensions>
      <bindingExtensions>
        <add name="pollingDuplexHttpBinding" type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement, System.ServiceModel.PollingDuplex, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </bindingExtensions>
    </extensions>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="PolicyProviderBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="RoboTrader.TheFloor.DashboardService">
        <endpoint address="" binding="webHttpBinding"
          behaviorConfiguration="PolicyProviderBehavior"
          contract="RoboTrader.DashboardService.IPolicyProvider"/>
        <endpoint address="DashboardService" binding="pollingDuplexHttpBinding"
          contract="RoboTrader.DashboardService.IDashboardService"/>
        <endpoint address="DashboardService/mex" binding="mexHttpBinding" 
          contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/" />
          </baseAddresses>
        </host>
      </service>
    </services>
</system.serviceModel>

In the Silverlight client code, I added a service reference, and that seems to have worked just fine. And the client fetches the cross-domain policy on the service as expected. However, when I call the main DashboardService methods, I get the CommunicationException, and a breakpoint in my server-side method is never reached. Here's the Silverlight ClientConfig file generated by adding the service reference:

<system.serviceModel>
    <bindings>
        <customBinding>
            <binding name="PollingDuplexHttpBinding_IDashboardService">
                <binaryMessageEncoding />
                <httpTransport maxReceivedMessageSize="2147483647"
                  maxBufferSize="2147483647" />
            </binding>
        </customBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:8732/DashboardService" 
            binding="customBinding"
            bindingConfiguration="PollingDuplexHttpBinding_IDashboardService"
            contract="Service.IDashboardService" 
            name="PollingDuplexHttpBinding_IDashboardService" />
    </client>
</system.serviceModel>

Are there any problems with this setup, or are there any additional things I need to do to get a polling duplex HTTP binding to work? Or do you at least know of how I can get more information about what the issue is?

Edit:

I just tried setting up the client and server bindings through code instead to see if it would help, but I still get the identical exception. Here's the server code:

var dboardService = new DashboardService();
ServiceHost host = new ServiceHost(dboardService);
host.AddServiceEndpoint(
    typeof(IDashboardService),
    new CustomBinding(
        new PollingDuplexBindingElement(),
        new BinaryMessageEncodingBindingElement(),
        new HttpTransportBindingElement()),
    "DashboardService");
host.Open();

And here's the client code:

private IDashboardService _svc = new DashboardServiceClient(
    new PollingDuplexHttpBinding(),
    new EndpointAddress("http://localhost:8732/DashboardService"));

Edit 2:

I tried changing the client code to this, but the same issue occurs:

private IDashboardService _svc = new DashboardServiceClient(
    new CustomBinding(
        new PollingDuplexBindingElement(),
        new BinaryMessageEncodingBindingElement(),
        new HttpTransportBindingElement()),
    new EndpointAddress("http://localhost:8732/DashboardService"));
A: 

try creating the endpoint through code, exactly the same way you're doing it now. But on the client side create the proxy like so.

CustomBinding binding = new CustomBinding(
                new PollingDuplexBindingElement(),
                new BinaryMessageEncodingBindingElement(),
                new HttpTransportBindingElement());


private IDashboardService _svc = new DashboardServiceClient(binding,
   new EndpointAddress("http://localhost:8732/DashboardService"));
Neil
I tried this and got the same result.
Jacob
+1  A: 

You've gotta be kidding me! I found the reason why this wasn't working in an MSDN article titled Network Security Access Restrictions in Silverlight:

One additional restriction on using the sockets classes is that the destination port range that a network application is allowed to connect to must be within the range of 4502-4534."

After changing my port number to 4505, the server code was reached after making a request from Silverlight.

Jacob
ive used ports 8080 - 8085 for my application and it works, technically you're not using System.Net.Sockets (which is limited to ports 4502-4534), rather HTTP, i think the problem lies elsewhere, you should figure it out before it pops up again when you least expect it
Neil
I too have been able to use a broader range of sockets when using plain HTTP. But this was my first time trying to use `pollingDuplexHttpBinding`. I am pretty sure that changing the port number was the only modification I made before things started to work, so maybe the restriction does apply to that binding. Have you used the higher port numbers with a duplex HTTP binding before?
Jacob
@Neil: Was you XAP file delivered from the same http server on port 8080-8085 per chance? There is no restriction on the port that XAP originates from and any other HTTP access from the XAP to the server on that port would be considered as a same-site access.
AnthonyWJones