当Silverlight同时遇上TCP和Http的WCF服务
如果只是单一的TCP通信
如果你的silverlight应用因为一些特殊原因跟WCF通信时使用的不是Http协议,而是TCP协议,并且是Host到控制台上的。那么假设是下面这个简单的服务
1,WCF中的主机服务代码如下
class Program { static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(HelloService)); host.Open(); Console.WriteLine("服t务?已?经-启?动ˉ!?"); } } [ServiceContract] interface IHelloService { [OperationContract] string SayHello(string name); } public class HelloService : IHelloService { public string SayHello(string name) { return "hello," + name; } }
2,app.config可以简单配置成这样
<configuration> <bindings> <netTcpBinding> <binding name="netTcpBindConfig"> <security mode="None"/> </binding> </netTcpBinding> </bindings> <services> <service name="HelloService"> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:4503/HelloService"/> </baseAddresses> </host> <endpoint address="" binding="netTcpBinding" contract="WCF.IHelloService"></endpoint> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" ></endpoint> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WCF.HelloServiceBehavior"> <serviceMetadata/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </configuration>
3,鉴于silverlight4在访问服务的时候会请求主机的80端口得到一个策略文件,如果你按照这个要求在wwwroot下放置这么个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>
那这个服务就OK了。可以正常提供服务了。
如果需要加载另外的DLL,且这DLL访问http的WCF服务呢?
也许您在VS2010中调试会OK,但是在部署到服务器上后,打开页面会发现一个错误,提示的居然是安全性错误。会是什么原因呢,我百思不得其解,奇怪的地方就在于,为什么在VS2010中调试加载的DLL可以正常访问服务,但是一发布就访问不到了呢。后来,在同事的提醒下,我在wwwroot下的文件clientaccesspolicy.xml中加了一行配置
<resource path="/" include-subpaths="true"/>
全部配置为:
<?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" />
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
再打开页面,通过!
补充:由于silverlight在访问WCF服务时,需要在80端口获取一个策略文件,而这个策略文件便是给了silverlight一个访问主机的权限。由于我们的silverlight应用本身是访问TCP协议的WCF的,所以需要在wwwroot下放一个策略文件允许TCP的访问,但是由于silverlight应用中又加载了一个DLL,这个DLL是访问HTTP协议的WCF的,所以在请求TCP授权的同时,需要获得HTTP的授权,而<resource path="/" include-subpaths="true"/> 这个配置节正是满足了访问IIS根目录及子目录的权限,当然,包括WCF服务在内。