博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SilverLight通过Net.TCP(NetTCPBinding)方式调用WCF服务
阅读量:5291 次
发布时间:2019-06-14

本文共 6127 字,大约阅读时间需要 20 分钟。

在SilverLight中通过标准的BasicHttpBinding来调用WCF服务是非常容易的, 只要通过VS的添加服务引用功能添加一下就直接能用了, 但是通过net.tcp绑定来调用则相当麻烦. 

 

一. 创建解决方案

首先在VS中创建一个新的SilverLight项目, 将项目命名为SilverLightTcpBindingSample, 在随后弹出的对话框中选择创建一个新的WebApplication作为SilverLight的宿主网站, 该网站的名字被自动命名为SilverLightTcpBindingSample.Web.

解决方案的结构为:

SilverLightTcpBindingSample(Solution)

    --SilverLightTcpBindingSample(SilverLight Project)

    --SilverLightTcpBindingSample.Web

 

二. 服务端的配置和部署

在SilverLightTcpBindingSample.Web项目中右击->Add->New Item->WCF Service, 保持默认的名字Service1, 项目中就会添加IService.cs和Service1.svc 两个文件.

在IService.cs中会自动生成一个名为IService1的接口 和一个默认的DoWork函数, 将它的定义稍做修改:

[ServiceContract]
public interface IService1
{
[OperationContract]
string DoWork(string text);
}

 

然后在Service1.svc中为这个函数添加点内容:

public class Service1 : IService1
{
public string DoWork(string text)
{
return string.Format("{0}, {1}", DateTime.Now.ToString("HH:mm:ss") , text.Length);
}
}

 

功能上就算完工了, 然后打开web.config, <system.serviceModel>节应该已经存在了, 如果不存在, 手工添加之. 

按下述代码定义<system.serviceModel>节:

 
 
 
 
 
 
binding="netTcpBinding"
bindingConfiguration="tcpBindingConfig1"
contract="SilverLightTCPBindingSample.Web.IService1">
 
 
binding="mexTcpBinding"
contract="IMetadataExchange">
 
 
 
 
 
 
 
 
 
 
multipleSiteBindingsEnabled="true" />
 

 

这里为不熟悉配置文件的同学稍微解释两句, 熟悉的请直接跳过这几段:

<bindings>节实际上是起configuration的作用, 它与任何的服务都不相关, 它定义具体某种binding的细节配置, 例如这里将tcpBinding的securityMode配置为None.

*需要注意的是: SilverLight不支持WCF的Security模型, 所以如果想在SL中调用此服务, 就必须把Security设置为None. 缺省模式下, SecurityMode是Transport, 所以这一节不可省略, 必须显式配置.

 

关于服务的信息都配置在Services节中. 这里有两个endpoint, 一个是供客户端调用的, 另一个是公布元数据的, 用于服务信息的生成. 在host节中添加的baseAddress需要注意, 4502这个端口号不是我瞎编的, 而是SilverLight只能使用4502至4534之间的端口( 我怎么知道的? 在SilverLight的异常中就有非常完整的提示, 这里节录一句: 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) , 所以这里就使用了4502端口.

下面的Behaviors节和serviceHostingEnvironment 节是自动生成的, 不用管它.

好了!

现在直接就把SilverLightTcpBindingSample.Web项目发布到某个文件夹下(这里发布到D:\Websites\SilverLightTcpBindingSample.Web). 然后开始IIS的配置. (因为只有IIS才支持net.tcp绑定, 所以必须发布到iis才能进行后续的测试)

2.1 检查WCF Activation

WCF Activation是Windows的一个可选组件, 默认情况下并没有安装, 只有先装上它, IIS才能支持非HTTP管道的WCF调用.

在控制面板->程序->打开或关闭Windows功能中, 找到.Net framework 3.5 ( 或4.5, 如下图)

这里因为我的操作系统是win8, 所以同时存在.net 3.5和.net 4.5两项, 如果是win7及以下的操作系统, 应该只有.net framework 3.5, 将.net 3.5项展开, 勾选下面的WCF Http Activation和WCF Non-HTTP Activation.

*需要注意的是: 当确认并安装完成上述两项以后, IIS会变异常, 运行任意一个IIS下的项目都会报如下错误:

未能从程序集"System.ServiceModel,Version=3.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"中加载类型"System.ServiceModel.Activation.HttpModule"

这时需要打开cmd, 定位到C:\Windows\Microsoft.NET\Framework\v4.0.30319目录下, 执行命令:  aspnet_regiis –i, 重新安装iis才能修复.

因此如果需要在正式的web服务器上安装WCF Activation, 需要注意这个问题.

 

2.2 编辑默认网站的net.tcp绑定端口

本来这是一件很简单的事情, 在IIS中找到默认网站节点, 右击->Edit Bindings:

 

在弹出的窗口中找到net.tcp, 点击edit(默认是808, 这里我已经改成了4502) :

然后在弹出的编辑框中把808:* 改成4502:* 即可:

但是, 我的win8系统无论是点Add, 还是编辑, 一点保存一定报错, 错误信息是: Object reference not set to an instance of an object, 对象空引用…

 

难以相信微软老大会犯这么低级的错误, 但是他们就是这么干了, 咱能怎么着? 我在网上查了一下, 也有其他人说遇到了跟我同样的问题, 但是微软并没有正面回复. 我不知道win7下有没有问题, 但是windows server 2008下确定是没有问题.

总之, 如果你跟我一样遇到了这个令人蛋疼的问题, 就得换一种方式来修改端口号:

先从上面的编辑窗口中把net.tcp删了(删除是不会报错的..) ,

然后打开cmd, 定位到C:\Windows\System32\inetsrv 目录下, 执行下述命令:

appcmd set site /site.name:"Default Web Site" /+bindings.[protocol='net.tcp',bindingInformation='4502:*']

执行完了以后回到刚才的编辑binding窗口, 会发现net.tcp已经绑定到4502端口了.

然后在默认网站中添加Application, 把刚才发布的项目添加进IIS.

在项目上右击->Manage Applicatoin->Advanced Settings:

在弹出的窗口中最下面一行, Enabled Protocols栏, 原来只有一个http, 在后面加一个逗号, 写上net.tcp.

 

2.3 允许跨域访问

SilverLight有一个很令人厌恶的设定就是跨域访问限制, 如果要跨域访问, 必须在服务网站上放一个policy文件… 不说废话了, 直接上代码:

 
 
 
 
 

在IIS中定位到默认网站节点, 右击, 选explore, 即可打开网站所在的目录:

如果你没有修改过它, 这个路径应该是 C:\inetpub\wwwroot,  在这个文件下新一个文本文件, 将其命名为clientaccesspolicy.xml, 注意!  这个文件名不能弄错, 必须叫这个名字, 要连同原文本文件的扩展名一起改掉( 什么? 你的电脑上没有显示扩展名? …你真的是一个程序员吗? ) , 然后随便用什么文本编辑器打开这个文件, 把上面那一段贴进去, 保存.

2.4 测试服务

服务端到这里就差不多算是大功告成了, 从IIS中浏览一下Service1.svc吧, 你应该会看到如下的界面:

 

当然, 其实这个界面还是有问题的(问题无处不在啊…) , 由于我们在配置服务的时候使用的是tcp元数据endpoint, 所以实际上很多人说在上面这个界面中, 自动生成的提示应该类似于这样:

svcutil.exe net.tcp://localhost:4502/……

而不是像我的电脑这样, 还是http打头的地址.

事实上, 同样的步骤, 我在windows server 2008上确实看到IIS自动生成的界面上写着net.tcp://打头的地址, 可惜, 那是我很久以后才看到的, 一开始我在我自己电脑上测试的时候, 为此困惑了很久, 不明白为什么它要生成http://打头的地址, 可能又是万恶的win8吧…(我到底为什么要装win8?)

any way, 如果你跟我一样看到的是http://打头的地址, 也没关系, 实际上还是可以通过tcp地址生成服务引用的.

打开developer command promp for vs2012, (在开始菜单->vs工具正面), 先输入d:, 回车, 切换到d盘根目录, 然后输入下述命令:

svcutil net.tcp://localhost:4502/SilverLightTCPBindingSample.Web/Service1.svc/mex

它应该会在d盘根目录下生成service1.cs和output.config两个文件:

当然, 实际上这一步骤并不是必需, 这仍然是为了做测试, 以确保服务确实被正确配置了.

如果到这一步都没有出现问题, 那就说明服务器端的配置和部署, 是真的接近于完成了… ( 如果仅在localhost上测试, 就已经完成了, 如果这是正式的web server, 很可能还需要在防火墙中开放4502端口, 所以说是接近于完成)

 

三. SilverLight端的配置

3.1 引用服务

这里是个有点歧义的地方, 我见有人说这里可以直接引用net.tcp://打头的地址, 但是我测试是不可以的, 用的是浏览器中的http地址: .

引用完成之后, 会自动生成一个ServiceReference.ClientConfig文件, 该文件的内容如下:

 

这里需要注意的是: 如果严格按照前面我所说的顺序操作, 这里会自动生成这个配置文件, 但是我一开始做的时候, 服务端的元数据endpoint用的不是tcp而是namedPipes, 生成的配置文件是空的, 我困惑了很久无解, 后来无奈在这里手动敲入的配置. 最后才发现原来是元数据endpoint的问题.

 

3.2 编写测试页面

非常简单地, 在MainWindow.xaml中放两个控件:

在cs文件中:

private void btn1_Click(object sender, RoutedEventArgs e)        {            var proxy = new ServiceReference1.Service1Client();            proxy.DoWorkCompleted += proxy_DoWorkCompleted;            proxy.DoWorkAsync(txt1.Text);        }        void proxy_DoWorkCompleted(object sender, ServiceReference1.DoWorkCompletedEventArgs e)        {            txt1.Text = e.Result;        }

编译整个项目, 运行SilverLightTcpBindingSample.Web项目中的SilverLightTCPBindingSampleTestPage.aspx, 会看到一个文本框和一个按钮 , 在文本框中输入一个a, 点击按钮, 应该会看到类似下面的界面:

前面是一个时间, 后面是字符串长度.

 

结语:

Tcp相对于basic http来说的性能优势显而易见, 所以为此麻烦一些是完全值得的.

转载于:https://www.cnblogs.com/Moosdau/archive/2012/12/27/2836609.html

你可能感兴趣的文章
Android 使用Parcelable序列化对象
查看>>
Python Web框架Django (零)
查看>>
Foxmail出现 错误信息:553 mailbox not found怎么解决
查看>>
spring_远程调用
查看>>
js 中基本数据类型和引用数据类型 ,,,, js中对象和函数的关系
查看>>
登录服务器,首先用到的5个命令
查看>>
多米诺骨牌
查看>>
区间DP 等腰三角形
查看>>
mysql 存储引擎对索引的支持
查看>>
Linq 学习(1) Group & Join--网摘
查看>>
asp.net 调用前台JS调用后台,后台掉前台JS
查看>>
【转】iOS 宏(define)与常量(const)的正确使用-- 不错
查看>>
【转】iOS开发UI篇—iPad和iPhone开发的比较
查看>>
【转】Android底层库和程序
查看>>
OnContextMenu事件(转)
查看>>
Comparación para 2019 Nueva Lonsdor K518S y K518ISE
查看>>
论文笔记——MobileNets(Efficient Convolutional Neural Networks for Mobile Vision Applications)
查看>>
从今天开始
查看>>
Attribute(特性)与AOP
查看>>
[翻译] CBStoreHouseTransition
查看>>