Search code examples
wcfsilverlightiisiis-7nettcpbinding

TCP error code 10013 Cross Domain Policy Error with netTcpBinding Service and Silverlight Client


Was wondeirng if anybody could get me out of my cross domain policy hell.

I have a duplex WCF service which uses netTcpBining, and the client is a Silverlight 4 app. When I self host the service, then it works perfectly and my Silverlight clients can consume the service with no problems. However when I host it in IIS 7, that's when the trouble starts. When I host it in IIS I'm able to see the service at:

http://localhost/Conference/VideoConferenceService.svc

And when I add a reference to the service which is hosted in IIS, and try to call it, I get a:

CommunicationException: Could not connect to net.tcp://localhost/Conference/VideoConferenceService.svc. The connection attempt lasted for a time span of 00:00:03.3071892. TCP error code 10013: An attempt was made to access a socket in a way forbidden by its access permissions.. This could be due to attempting to access a service in a cross-domain way while the service is not configured for cross-domain access. You may need to contact the owner of the service to expose a sockets cross-domain policy over HTTP and host the service in the allowed sockets port range 4502-4534.

Or if seeing the actual error helps inspire those who have seen it before, here is what it throws at me in Reference.cs:

enter image description here

I have checked out almost every solution suggested regarding solving the cross-domain policy error, and I've put my clientaccesspolicy.xml in my default website root in IIS, and also in wwwroot. I've also turned off all my firewalls. I'm able to see the policy at http://localhost/clientaccesspolicy.xml and also at http://127.0.0.1/clientaccesspolicy.xml but I still get this error.

Here is my web.config for the service hosted in IIS 7:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <runtime>
    <gcServer enabled="true" />
  </runtime>

  <system.web>
    <compilation debug="false" />
  </system.web>
   <system.serviceModel>
     <services>
       <service name="VideoServer.VideoConferenceService">
         <endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService" contract="VideoServer.IVideoConferenceService" />
         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
         <host>
           <baseAddresses>
                <add baseAddress="net.tcp://localhost:4502/VideoServer/" />
           </baseAddresses>
         </host>
       </service>
     </services>

    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_IVideoConferenceService" portSharingEnabled="true" transactionFlow="false" transferMode="Buffered" listenBacklog="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="24.20:31:23.6470000" openTimeout="24.20:31:23.6470000" receiveTimeout="24.20:31:23.6470000" sendTimeout="24.20:31:23.6470000">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <reliableSession enabled="false" />
          <security mode="None">
            <message clientCredentialType="None" />
            <transport protectionLevel="None" clientCredentialType="None" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="False" />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
    <system.webServer>
        <directoryBrowse enabled="true" />
    </system.webServer>

</configuration>

And here is the Silverlight client's ServiceReferences.ClientConfig file:

<configuration>
    <system.serviceModel>
        <bindings>
            <customBinding>
                <binding name="NetTcpBinding_IVideoConferenceService">
                    <binaryMessageEncoding />
                    <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://localhost/Conference/VideoConferenceService.svc"
                binding="customBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService"
                contract="ServiceReference1.IVideoConferenceService" name="NetTcpBinding_IVideoConferenceService" />
        </client>
    </system.serviceModel>
</configuration>

Has anybody got any suggestions? This annoying error has taken days of my time thus far. Any help would be greatly appreciated.

EDIT

When I check the files being retrieved in my web sessions using fiddler, it shows that my browser is retrieving the client access policy file, so I think the error lies somewhere else and WCF is just throwing this error at me? I've also set IE9 to clear its cache everytime its close. Take a look below.

enter image description here


Solution

  • Well I just managed to get it working. Couple of points worth mentioning are that:

    1. If you look at the erroneous ServiceReferences.ClientConfig that I posted above (generated by visual studio when I gave the service address as: http://localhost/Conference/VideoConferenceService.svc ) you can see that the netTcp port which is 4502, was not generated as part of the endpoint, this is what what causing the TCP error 10016 (EndpointNotFoundException) as well as TCP error 10013. The correct ServiceReferences.ClientConfig is actually:

    <configuration>
        <system.serviceModel>
            <bindings>
                <customBinding>
                    <binding name="NetTcpBinding_IVideoConferenceService">
                        <binaryMessageEncoding />
                        <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    </binding>
                </customBinding>
            </bindings>
            <client>
                <endpoint address="net.tcp://localhost:4502/Conference/VideoConferenceService.svc"
                    binding="customBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService"
                    contract="ServiceReference1.IVideoConferenceService" name="NetTcpBinding_IVideoConferenceService" />
            </client>
        </system.serviceModel>
    </configuration>
    

    2. When I was hosting my service in IIS 7, I was giving the port range 808:* as the netTcp ports, whereas I should have given 4502:* as the port range, like below:

    enter image description here

    Also from what I gathered, the website hosting the service should be on port 80, as Silverlight will look in localhost:80/ClientAccessPolicy.xml for the client access policy file.

    And just for the record, for those who stumble across this same problem, this web.config managed to work in IIS:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.web>
        <compilation debug="false" />
      </system.web>
    
       <system.serviceModel>
         <services>
           <service name="VideoServer.VideoConferenceService">
             <endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService" contract="VideoServer.IVideoConferenceService" />
             <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
           </service>
         </services>
    
        <bindings>
          <netTcpBinding>
            <binding name="NetTcpBinding_IVideoConferenceService" portSharingEnabled="false" transactionFlow="false" transferMode="Buffered" listenBacklog="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="24.20:31:23.6470000" openTimeout="24.20:31:23.6470000" receiveTimeout="24.20:31:23.6470000" sendTimeout="24.20:31:23.6470000">
              <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
              <reliableSession enabled="false" />
              <security mode="None">
                <message clientCredentialType="None" />
                <transport protectionLevel="None" clientCredentialType="None" />
              </security>
            </binding>
          </netTcpBinding>
        </bindings>
    
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="True" />
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
        <system.webServer>
            <directoryBrowse enabled="true" />
        </system.webServer>
    </configuration>
    

    Also worth noting that you don't need to put any ports or base addresses in the web.config for IIS. It will create the service endpoint using the port 4502, I tried changing it to 4503, 4522 etc. and interestingly it didn't work with those ports, only with 4502.