Silverlight与自托管WCF使用TCP双工通信

“跨域访问”问题

异常信息

未能连接到 net.tcp://localhost:4503/IMyService。连接尝试的持续时间为 00:00:00.3300189。TCP 错误代码 10013: 试图以其访问权限所禁止的方式访问套接字。。原因可能是,试图以跨域的方式访问某服务,而该服务的配置不支持跨域访问。您可能需要与服务的所有者联系,以公开通过 HTTP 的套接字跨域策略,并在允许的套接字端口范围 4502-4534 之内承载该服务。

解决

让客户端能以“http://<<YourNetTcpIPAddress>>:80/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>



解决方案

ClientCrossDomainAccessPolicy类

using System;

using System.IO;

using System.ServiceModel;

using System.ServiceModel.Description;

using System.ServiceModel.Web;

using System.Text;



public static class ClientCrossDomainAccessPolicy

{

    [ServiceContract]

    public interface IPolicy

    {

        //确定可以访问“http://localhost:80/clientaccesspolicy.xml"

        [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]

        Stream GetSilverlightPolicy();



        //确定可以访问“http://localhost:80/crossdomain.xml"

        [OperationContract, WebGet(UriTemplate = "/crossdomain.xml")]

        Stream GetFlashPolicy();

    }



    class Policy : IPolicy

    {

        #region IClientAccessPolicy Members



        Stream StringToStream(string result)

        {

            var oc = WebOperationContext.Current;

            if (oc == null)

                throw new NullReferenceException("WebOperationContext");



            oc.OutgoingResponse.ContentType = "application/xml";

            return new MemoryStream(Encoding.UTF8.GetBytes(result));

        }

        public Stream GetSilverlightPolicy()

        {

            const string result = @"<?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>";

            return StringToStream(result);

        }



        public Stream GetFlashPolicy()

        {

            const string result = @"<?xml version=""1.0""?>

<!DOCTYPE cross-domain-policy SYSTEM ""http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"">

<cross-domain-policy>

    <allow-access-from domain=""*"" />

</cross-domain-policy>";

            return StringToStream(result);

        }



        #endregion

    }



    public static ServiceHost GetHost()

    {

        var policyHost = new ServiceHost(typeof(Policy), new Uri("http://localhost:80"));//端口必须为80。若非TCP,像如HTTP托管,则直接将Policy发布至根下即可

        policyHost.AddServiceEndpoint(typeof(IPolicy), new WebHttpBinding(), string.Empty).Behaviors.Add(new WebHttpBehavior());



        return policyHost;

    }

}



使用方式

            /////////////////////////////////////////////////

            //加上以下三行以解决Silverlight跨域访问问题。实现效果:可以直接访问“http://localhost:80/clientaccesspolicy.xml"与“http://localhost:80/crossdomain.xml"读取跨域授权配置文件

            using (var policyHost = ClientCrossDomainAccessPolicy.GetHost())

            {

                policyHost.Open();



//写你自己的代码...



效果截图

Silverlight与自托管WCF使用TCP双工通信

参考

Policy file for NetTcp

Using Silverlight 4 and Net.TCP Duplex Callbacks

示例代码下载

你可能感兴趣的:(silverlight)