如何配置net.tcp 的WCF服务

如何配置net.tcp 的WCF服务,第1张

这个方法里,我们有两个函数,一个能够根据学生点获取学生全名,另一个是根据学生点获取学生的实体对象。

好了,让我们来编译这个项目,得到一个WCFServiceGeneratedByConfig.exe文件。

然后,我们需要配置文件来让服务器端启动,所以这里我们要用WCF Service Configuration Editor

工具来进行,由于在VS2008 和VS2010中带有这个软件,我们可以直接通过菜单->Tools->WCF Service Configuration Editor来打开。

首先,点击File->New config, 打开Service的Configuration界面。

然后,点击Create a new service…,在d出的界面中,我们选择刚才生成的那个WCFServiceGeneratedByConfig.exe文件。双击之后,软件自动显示出了里面含有的Service:

点选那个Service,然后点击两次next,我们会看到出现了选择Communation Mode的界面,这里由于我们用的是net.tcp,所以我选择了第一个:TCP。

然后点击Next,我们会看到要我们填写EndPoint,这里我随便填写了一个:

之后,点击Next知道Finish,然后,我们的最基本的配置就结束了。

回到Config界面之后,我们点击Advanced->Service Behaviors->New Service Behavior Configuration,在d出的界面中,我们点击Add->serviceMetadata:

然后点击Add,我们就添加了一个Behavior Element。点击刚刚生成的serviceMetadata节点,在显示的界面中,设置HttpGetEnabled为true。

然后点击原来的Service节点下的Host节点,在Base Address栏目下单击Add,添加如下的Base Address:

最后点击OK。然后点击菜单File->Save As 保存到项目文件夹下即可。

这里是生成的代码:

View Code

这一步做完后,我们需要让服务能够启动,怎么启动呢?请看下面的代码:

View Code

代码中的注释部分非常重要,我们一定要添加,否则下面的步骤不能进行,具体的原因,参加我的另一篇文章:在net.tcp模式下,由SvcUtil.exe生成代理类文件和配置文件

然后运行这个ConsoleApplication。

接下来,找到SvcUtil.exe,C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\SvcUtil.exe,在CMD窗口下运行如下命令:

C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\SvcUtil.exe net.tcp://127.0.0.1:50001/StudentServiceEndPoint

这样,这个小工具就会自动的给我们生成代理类和配置文件

Microsoft (R) Service Model Metadata Tool

[Microsoft (R) Windows (R) Communication Foundation,版本 3.0.4506.2152]

版权所有(c) Microsoft Corporation。保留所有权利。

正在尝试使用 WS-Metadata Exchange 从“net.tcp://127.0.0.1:50001/StudentServiceEndPoint”下载元数据。此 URL 不支持 DISCO。

正在生成文件...

E:\WCF\WCF_ChatRoom\StudentService.cs

E:\WCF\WCF_ChatRoom\output.config

请按任意键继续. . .

客户端的配置步骤

接下来,新建一个WindowsFormsApplication程序,将这个代理类拷入,配置文件修改名称为App.config拷入,

然后在Form1.cs中拖入一个文本框,一个按钮,一个DataGridView,后台代码如下:

View Code

启动这个实例,输入学生ID,我们成功得到了服务端返回的值。

在本机和公网上的运行结果

那么能不能在公网上使用呢?呵呵,这个当然,将服务端拷贝到外网的一台机器上,然后修改服务器端的配置文件中的地址为:net.tcp://169.*.*.124:50001/ StudentServiceEndPoint,然后将本机的配置文件中的地址也修改为这个,最后运行,依然能够得到返回的结果。

这个问题是这样来的。

首先,你应该了解一下使用WCF方法异步(特指使用代理工具生成Begin/EndXXX异步方法)时Begin和End方法的特性。

BeginAdd在执行时并不会阻塞线程,它会立即返回一个IAsyncResult同步对象,该对象是受同步保护的内存块,会跨越一切困难维持着自身的一致性。当然,如果传入了一个回调方法(你的AddCallBack),则BeginAdd开始执行时会在调用方偷偷建立一个线程以等待同步信号,当服务端的Add方法执行完毕后本地线程会调用该回调。

再说EndAdd。此方法实际上是作为一种“保险”来使用,而非你的EndAdd(BeginAdd(...))这样。EndAdd是会阻塞线程的方法,实际的意义是“等待到Add方法结束并返回”。如此,你应该可以理解注释掉的

Console.WriteLine(sc.EndAdd(sc.BeginAdd(1, 2, 1000, null, null)))

是如何工作的了:

首先sc要求服务端异步执行Add方法且无回调,BeginAdd立即返回,但是EndAdd又要求等待至服务端Add结束。综上,此行代码其实等同于Console.WriteLine(sc.Add(1,2,1000))

(这里顺便说一句,如果传入了一个回调,在回调开始执行的同时EndAdd也返回了)

那么

//为什么用这两行代码,最后GetOperateCount的结果是2

         

Console.WriteLine(sc.EndAdd(sc.BeginAdd(1, 2, 1000, null, null)))

             Console.WriteLine(sc.EndSub(sc.BeginSub(9, 4, 2000, null, null)))

因为其实你的代码都是“同步”的,先加,后减,然后“同步”GetOperationCount。

这一点是很容易验证的,比如你可以在以上两行后都加Console.WriteLine(sc.GetOperationCount())(此为同步方法)可以很明显的看出是先加后减的。

那么

//为什么用这两行代码,最后GetOperateCount的结果是0

         

IAsyncResult iaAdd= sc.BeginAdd(1, 2, 1000, AddCallback, sc)

            IAsyncResult iaSub = sc.BeginSub(1, 2, 1000, SubtractCallback, sc)

这个也很好理解,iaAdd和iaSub都被立即返回了,然后立刻”同步“打印了结果(sc.EndGetOperationCount(sc.BeginGetOperationCount(...))等同于sc.GetOperationCount())。

因为服务端方法执行需要时间,又或者是首次服务实例(你的服务InstanceContextMode.Single)实例化需要时间,*很可能*在服务端GetOperationCount方法会先于Add和Sub完成并返回,导致了输出为0。

这个也是可以验证的。

验证一:在GetOperationCount服务方法内加入

System.Threading.Thread.Sleep(5000)

你会看到输出是正确的2,因为5秒内Add和Sub早已返回,连AddCallback和SubtractCallback都已执行完毕(从两个回调的输出可见)。

验证二:我们在服务端Add方法内延时1秒,在Sub方法内延时10秒,在GetOperationCount方法内延时5秒。猜猜看结果?先加再输出再减。(如果条件允许,请在三个服务方法上加断点,可以更好的观察到执行顺序)

以上为你的问题分析。这里我提个小小的建议:请按标准的做法来写程序。

如果需要同步执行,就直接执行同步方法;如果需要执行异步方法,请使用IAsyncResult及回调进行处理。End方法作为一种保险措施,是为了在本地已得知异步执行完毕后通知CLR释放相关资源所用,应该在你等待超过预期时间或者已经处理完异步结果后调用,通常End方法位于回调中,也有少数时间因为同步结果在其他地方处理因为挪到外部的情况。

异步有很多种实现方法,选择适合自己的一种。在不需要处理中间的过程数据时,我个人更喜欢下面的做法。至少省掉了生成异步方法的 *** 作。

ThreadPool.QueueUserWorkItem(()=>

{            double result = sc.Sub(ar)            Console.WriteLine("Subtract Result : " + result)})

就这么多,有问题请PM。

使用“添加服务引用”对话框可在当前解决方案中、在本地、在局域网中或在 Internet 上搜索 WCF 数据服务。说明对于在以下说明中使用的某些 Visual Studio 用户界面元素,您的计算机可能会显示不同的名称或位置。这些元素取决于您所使用的 Visual Studio 版本和您所使用的设置。有关更多信息,请参见 Visual Studio 设置。添加服务引用添加对外部服务的引用在“解决方案资源管理器”中,右击要添加服务的项目的名称,然后单击“添加服务引用”。将出现“添加服务引用”对话框。在“地址”框中,输入服务的 URL,然后单击“前往”搜索该服务。如果此服务实现了用户名和密码安全性,系统可能会提示您输入用户名和密码。说明只应引用来自受信任源的服务。添加来自不受信任源的引用可能会降低安全性。还可以从“地址”列表中选择 URL,此列表存储了前 15 个在其中找到了有效服务元数据的 URL。执行搜索时将显示一个进度栏。随时都可以通过单击“停止”来停止搜索。在“服务”列表中,展开要使用的服务的节点,并选择一个实体集。在“命名空间”框中,输入要用于引用的命名空间。单击“确定”以将此引用添加到项目。将生成一个服务客户端(代理),并且描述此服务的元数据将添加到 app.config 文件中。添加对当前解决方案中的服务的引用在“解决方案资源管理器”中,右击要添加服务的项目的名称,然后单击“添加服务引用”。将出现“添加服务引用”对话框。单击“发现”。当前解决方案中的所有服务(WCF 数据服务和 WCF 服务)都将添加到“服务”列表中。在“服务”列表中,展开要使用的服务的节点,并选择一个实体集。在“命名空间”框中,输入要用于引用的命名空间。单击“确定”以将此引用添加到项目。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/bake/11724790.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存