locked
WCF via net.tcp, Communication Exception RRS feed

  • Question

  • Hi guys!!!

    I really need your help I don’t know what to do. I am working on the WCF service via netTcpBinding for Silverlight application. I hosted it on the IIS 7.5 and added the reference to the Silverlight application but keep getting this error :

    Could not connect to net.tcp://localhost:4528/WcfChatService/ChatService.svc. The connection attempt lasted for a time span of 00:00:00.1760100. 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.

    I researched a lot through articles, forums and blogs. So, what I did to make it work: 

    • I have this web.config for my service
      <!--
        For more information on how to configure your ASP.NET application, please visit
        http://go.microsoft.com/fwlink/?LinkId=169433
        -->
      
      <configuration>
         <system.web>
          <compilation debug="true" targetFramework="4.0" />
        </system.web>
      
        <system.serviceModel>   
          <behaviors>
            <serviceBehaviors>
              <behavior name="">
                <serviceMetadata httpGetEnabled="true" />
                <dataContractSerializer maxItemsInObjectGraph="2147483647" />
                <serviceDebug includeExceptionDetailInFaults="false" />
                <!--<serviceTimeouts transactionTimeout="00:05:00" />-->
                <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" maxConcurrentInstances="2147483647"/>        
              </behavior>
            </serviceBehaviors>
          </behaviors>
          <bindings>
            <netTcpBinding>
              <binding name="Chat" portSharingEnabled="true" >
                <readerQuotas maxArrayLength="2147483647" />
                <security mode="None" />
              </binding>
            </netTcpBinding>
          </bindings>
          <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
          <services>
            <service name="WcfChatService.ChatService">
              <endpoint address="" binding="netTcpBinding" bindingConfiguration="Chat" contract="WcfChatService.ChatService" />
              <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
              <host>
                <baseAddresses>
                  <add baseAddress="http://localhost:80/" />
                  <add baseAddress="net.tcp://localhost:4528/WcfChatService/ChatService.svc" />
                </baseAddresses>
              </host>
            </service>
          </services>
        </system.serviceModel>
        <system.webServer>
          <directoryBrowse enabled="true"/>
        </system.webServer>
      </configuration> 
    • I have file clientaccesspolicy.xml opened in browser like http://localhost/clientaccesspolicy.xml because I put  it in c:\inetpub\wwwroot\. The content is next: 
    • <?xml version="1.0" encoding="utf-8"?>
      <access-policy>
        <cross-domain-access>
          <policy>
            <allow-from http-request-headers="*">
              <domain uri="*" />
            </allow-from>
            <grant-to>
              <resource path="/" include-subpaths="true" />
              <socket-resource port="4502-4530" protocol="tcp" />
            </grant-to>
          </policy>
        </cross-domain-access>
      </access-policy>
      
    • I have NetTcp Listener Adapter, NetTcp Port Sharing service started, I have Windows Communication Foundation Non HTTP Activation on.
    •  I have all Firewalls off.
    • On IIS I’ve added net.tcp binding.
    • I have  the Console application to listen on port 943 with the code, because I am not sure if it’s needed in SL4:
      namespace SilverlightSocketPolicy
      {
          public static class SocketPolicy
          {
              public const string Policy = @"
      <?xml version=""1.0"" encoding =""utf-8""?>
      <access-policy>
        <cross-domain-access>
          <policy>
            <allow-from>
              <domain uri=""*"" />
            </allow-from>
            <grant-to>
              <socket-resource port=""4502-4530"" protocol=""tcp"" />
            </grant-to>
          </policy>
        </cross-domain-access>
      </access-policy>
      ";
          }
      
      
          // Encapsulate and manage state for a single connection from a client
          class PolicyConnection
          {
              Socket m_connection;
      
              // buffer to receive the request from the client
              byte[] m_buffer;
              int m_received;
      
              // the policy to return to the client
              byte[] m_policy;
      
              // the request that we're expecting from the client
              static string s_policyRequestString = "<policy-file-request/>";
      
              public PolicyConnection(Socket client, byte[] policy)
              {
                  m_connection = client;
                  m_policy = policy;
      
                  m_buffer = new byte[s_policyRequestString.Length];
                  m_received = 0;
      
                  try
                  {
                      // receive the request from the client
                      m_connection.BeginReceive(m_buffer, 0, s_policyRequestString.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);
                  }
                  catch (SocketException)
                  {
                      m_connection.Close();
                  }
              }
      
              // Called when we receive data from the client
              private void OnReceive(IAsyncResult res)
              {
                  try
                  {
                      m_received += m_connection.EndReceive(res);
      
                      // if we haven't gotten enough for a full request yet, receive again
                      if (m_received < s_policyRequestString.Length)
                      {
                          m_connection.BeginReceive(m_buffer, m_received, s_policyRequestString.Length - m_received, SocketFlags.None, new AsyncCallback(OnReceive), null);
                          return;
                      }
      
                      // make sure the request is valid
                      string request = System.Text.Encoding.UTF8.GetString(m_buffer, 0, m_received);
                      if (StringComparer.InvariantCultureIgnoreCase.Compare(request, s_policyRequestString) != 0)
                      {
                          m_connection.Close();
                          return;
                      }
      
                      // send the policy
                      m_connection.BeginSend(m_policy, 0, m_policy.Length, SocketFlags.None, new AsyncCallback(OnSend), null);
                  }
                  catch (SocketException)
                  {
                      m_connection.Close();
                  }
              }
      
              // called after sending the policy to the client; close the connection.
              public void OnSend(IAsyncResult res)
              {
                  try
                  {
                      m_connection.EndSend(res);
                  }
                  finally
                  {
                      m_connection.Close();
                  }
              }
          }
      
          // Listens for connections on port 943 and dispatches requests to a PolicyConnection
          class PolicyServer
          {
              Socket m_listenerIPv4;
              Socket m_listenerIPv6;
              byte[] m_policy;
      
              // pass in the path of an XML file containing the socket policy
              public PolicyServer(string policyContents)
              {
                  m_policy = Encoding.UTF8.GetBytes(policyContents);
      
                  // Create the Listening Sockets            
                  m_listenerIPv4 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                  m_listenerIPv4.Bind(new IPEndPoint(IPAddress.Any, 943));
                  m_listenerIPv4.Listen(10);
                  m_listenerIPv4.BeginAccept(new AsyncCallback(OnConnection), m_listenerIPv4);
                  Console.WriteLine("Listenting on IPv4 port 943.");
      
                  if (System.Net.Sockets.Socket.OSSupportsIPv6)
                  {
                      m_listenerIPv6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
                      m_listenerIPv6.Bind(new IPEndPoint(IPAddress.IPv6Any, 943));
                      m_listenerIPv6.Listen(10);
                      m_listenerIPv6.BeginAccept(new AsyncCallback(OnConnection), m_listenerIPv6);
                      Console.WriteLine("Listenting on IPv6 port 943.");
                  }
                  else
                  {
                      Console.WriteLine("IPv6 is not supported by the system.");
                  }
              }
      
              // Called when we receive a connection from a client
              public void OnConnection(IAsyncResult res)
              {
                  Socket listener = (Socket)res.AsyncState;
                  Socket client = null;
      
                  try
                  {
                      client = listener.EndAccept(res);
                  }
                  catch (SocketException)
                  {
                      return;
                  }
      
                  // handle this policy request with a PolicyConnection
                  PolicyConnection pc = new PolicyConnection(client, m_policy);
      
                  // look for more connections
                  listener.BeginAccept(new AsyncCallback(OnConnection), listener);
              }
      
              public void Close()
              {
                  m_listenerIPv4.Close();
                  if (m_listenerIPv6 != null)
                  {
                      m_listenerIPv6.Close();
                  }
              }
          }
      
          public class Program
          {
              static void Main(string[] args)
              {
                  Console.WriteLine("TCP Socket Policy Server for Silverligth Applications");
                  PolicyServer ps = new PolicyServer(SocketPolicy.Policy);
                  Console.WriteLine("Press <ENTER> to terminate the server...");
                  Console.ReadLine();
                  ps.Close();
              }
          }
      }

    The most interesting  thing is that I managed to make it  work(don’t really know how because for a long time I kept getting  the same error  ), but I deleted DefaultWebSite.Then I recreated it based on DefaultWebPool with ID= 1 and with enabled net.tcp, but I started getting Communication error. 

     I don’t know what to do. Help me, please!!!  I will be very thankful for any ideas !!! Thanks in advance

    Tuesday, March 13, 2012 6:23 PM

Answers

  • Hi,

    In my opinion, Silverlight4 supports NetTcpTransportBindingElement not NetTcpBinding. Thus, to create a silverlight compatiable nettcpbinding, you need turn off security setting. Please refer to link which is a blog explaining it more clearly:

    http://mogliang.blogspot.com/2010/08/how-to-consume-wcf-service-with.html

    Besides, it may be caused by proxy, so please check if the proxy require the windows credential.

    If it doesn't work, please check with Fiddler to see what is request and the response from the server.

    Thursday, March 15, 2012 5:45 AM

All replies

  • Guys, maybe someone already solved this problem? Any ideas?

    Wednesday, March 14, 2012 9:28 AM
  • Hi,

    In my opinion, Silverlight4 supports NetTcpTransportBindingElement not NetTcpBinding. Thus, to create a silverlight compatiable nettcpbinding, you need turn off security setting. Please refer to link which is a blog explaining it more clearly:

    http://mogliang.blogspot.com/2010/08/how-to-consume-wcf-service-with.html

    Besides, it may be caused by proxy, so please check if the proxy require the windows credential.

    If it doesn't work, please check with Fiddler to see what is request and the response from the server.

    Thursday, March 15, 2012 5:45 AM
  • Thanks for the advice a lot! I'll try it and will write what i've got.

    Thursday, March 15, 2012 6:43 AM