【问题标题】:Silverlight WCF netTcpBinding problemSilverlight WCF netTcpBinding 问题
【发布时间】:2011-02-21 21:57:19
【问题描述】:

尝试通过 Silverlight 调用带有 netTcpBinding 的 WCF,但出现错误:

"TCP 错误代码 10013:尝试以访问权限禁止的方式访问套接字。这可能是由于尝试以跨域方式访问服务而未配置服务跨域访问。您可能需要联系服务的所有者以通过 HTTP 公开套接字跨域策略,并将服务托管在允许的套接字端口范围 4502-4534 中。”

我的 WCF 服务托管在 IIS7 中,绑定到:

http://localhost.myserivce.com 在端口 80 和 net.tcp 在端口 4502

如果我浏览它,我可以看到http://localhost.myserivce.com/myservice.svc(我的主机文件将这个域指向本地主机)。 我也可以看到http://localhost.myserivce.com/clientaccesspolicy.xml

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
   <cross-domain-access>
      <policy>
         <allow-from http-request-headers="*">
            <domain uri="*" />
         </allow-from>
         <grant-to>
            <socket-resource port="4502-4534" protocol="tcp" />
         </grant-to>
      </policy>
   </cross-domain-access>
</access-policy>

我做错了什么?

【问题讨论】:

    标签: wcf silverlight-4.0 nettcpbinding clientaccesspolicy.xml


    【解决方案1】:

    如果您尝试在端口范围 4502-4534 中建立 TCP 连接,Silverlight 将首先在端口 943 上发布请求以检索客户端访问策略文件内容 - 它不会读取位于 http://localhost.myserivce.com/clientaccesspolicy.xml 的文件,因为这仅适用于 HTTP 请求。 您需要将服务器配置为侦听 TCP 端口 943,期望请求字符串等于 &lt;policy-file-request/&gt; 并使用 xml 文件内容进行回复。

    以下代码显示了一个基本实现,您需要使用端口 943 将其传递给本地 IPEndPoint:

    public class SocketPolicyServer
    {
        private const string m_policyRequestString = "<policy-file-request/>";
        private string m_policyResponseString;
        private TcpListener m_listener;
        bool _started = false;
    
        public SocketPolicyServer()
        {
            m_policyResponseString = File.ReadAllText("path/to/clientaccesspolicy.xml");
        }
    
        public void Start(IPEndPoint endpoint)
        {
            m_listener = new TcpListener(endpoint);
            m_listener.Start();
            _started = true;
            m_listener.BeginAcceptTcpClient(HandleClient, null);
        }
    
        public event EventHandler ClientConnected;
        public event EventHandler ClientDisconnected;
    
        private void HandleClient(IAsyncResult res)
        {
            if(_started)
            {
                try
                {
                    TcpClient client = m_listener.EndAcceptTcpClient(res);
                    m_listener.BeginAcceptTcpClient(HandleClient, null);
                    this.ProcessClient(client);
                }
                catch(Exception ex)
                {
                    Trace.TraceError("SocketPolicyServer : {0}", ex.Message);
                }
            }
        }
    
        public void Stop()
        {
            _started = false;
            m_listener.Stop();
        }
    
        public void ProcessClient(TcpClient client)
        {
            try
            {
                if(this.ClientConnected != null)
                    this.ClientConnected(this, EventArgs.Empty);
    
                StreamReader reader = new StreamReader(client.GetStream(), Encoding.UTF8);
                char[] buffer = new char[m_policyRequestString.Length];
                int read = reader.Read(buffer, 0, buffer.Length);
    
                if(read == buffer.Length)
                {
                    string request = new string(buffer);
    
                    if(StringComparer.InvariantCultureIgnoreCase.Compare(request, m_policyRequestString) == 0)
                    {
                        StreamWriter writer = new StreamWriter(client.GetStream());
                        writer.Write(m_policyResponseString);
                        writer.Flush();
                    }
                }
            }
            catch(Exception ex)
            {
                Trace.TraceError("SocketPolicyServer : {0}", ex.Message);
            }
            finally
            {
                client.GetStream().Close();
                client.Close();
                if(this.ClientDisconnected != null)
                    this.ClientDisconnected(this, EventArgs.Empty);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      自 SL4 RTM 起,这已更改。 SL4 net.tcp 客户端不会在 tcp 943 上查找客户端访问策略,而是使用旧方法,即使用 Web 服务器的根端口 80。奇怪的是,这在任何地方都没有得到很好的记录,但我可以确认这是发布时的行为。

      最重要的是,从 SL4 RTM 开始,您描述的方法应该有效,而此处的其他答案则无效。

      【讨论】:

        猜你喜欢
        • 2014-08-25
        • 2013-11-19
        • 2011-02-04
        • 1970-01-01
        • 1970-01-01
        • 2011-01-07
        • 2012-01-13
        • 1970-01-01
        • 2011-05-03
        相关资源
        最近更新 更多