加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

wcf的 msmq

发布时间:2020-12-17 02:41:56 所属栏目:安全 来源:网络整理
导读:PDC 2005 的时候,又很多专场关于Indigo,现在改为Windows Communication Framework. Indigo能够很好的支持SOA,接下来举一个例子. 把消息队列跟Indigo连接起来. 面向服务的应用体系结构,一定需要一个基础的消息通讯平台. 这个年代 WebService 以其WS-*,很好的
PDC 2005 的时候,又很多专场关于Indigo,现在改为Windows Communication Framework. Indigo能够很好的支持SOA,接下来举一个例子. 把消息队列跟Indigo连接起来.

面向服务的应用体系结构,一定需要一个基础的消息通讯平台. 这个年代 WebService 以其WS-*,很好的适合了这个应用场景. 在没有Indigo之前,微软的.net 就得用WSE,目前已经是3.0了.

而消息队列,作为一个异步,可靠的消息交换平台,还是又很多自己的用途.

而Indigo呢,事实上Indigo 大大的包含和整合集成了各种通讯协议,基础件,编程模型.

对于一个服务而言,需要一个Endpoint,需要一个Contract,还需要一个实现.? 而 Service 的调用者和提供者之间,则可以通过广泛存在的现有协议进行通讯. 而Indigo 就是把这些东西全部都给你绑定再一个Framework中,换言之以前你要写很多的东西,现在代码极度简化.

就好比以前用API Create 一个稍微pp一点的窗体,现在只要实例化一个类就可以了.

接下来,装了SDK的,可以很快cover一个例子.

我提供了一个最简单的Service,是HelloWorld Service,当然Service 只要是自治,有明确的边界,基于Contract.. 你也可以把HelloServie 当作一个订单处理的service.

面向服务,首先要有一个Contract,这个跟SQL 2005中的Service Broker一样

在.net 中,我们可以对类做一些属性标记,系统会自动提取这些Contract,所谓contract包含提供什么功能,需要什么输入输出.

比如我新建一个类. 可是这个类加了一些特殊的属性,可以自动生成类似wsdl一样的contract.

??[ServiceContract()]

????
public ? interface ?IService1

????
{

????????[OperationContract(IsOneWay
=true)]

????????
void?MyOperation1(string?myValue);

????}


????
public ? class ?service1?:?IService1

????
{

????????
public?void??MyOperation1(string?myValue)

????????
{

???????????System.IO.StreamWriter?sw
=?System.IO.File.AppendText("C://Demo.txt");

???????????sw.WriteLine(DateTime.Now.ToString()?
+?"?Received:?"?+?myValue);

???????????sw.Close();

????????}

????}

严格意义上讲,myvalue这个参数应该有个schema来定义,由于是基本的数据类型,可以忽略.

这边加了很多的属性,用来标记contract的内容.

接下来就是需要有一个集成来Host 这些服务. 在Indigo中,默认提供了很多的绑定.当然不同绑定有其使用场景. 比如以前我们用webservice,是基于Soap/xml的,绝大多数是http的通讯. 而remoting可能是tcp或者http,Com+ queued Component则是用msmq. 在indigo中你只要选择一下就可以. 比如我用msmq作为通讯协议,当然msmq是异步的. 我们的服务就无法直接有返回值.
我特意加了一个oneway的属性.
接下来,我选择一种通讯的协议.msmq来Listen
所以代码跟remoting很像,我用一个console来host这个service.

? internal ? class ?MyServiceHost

????
{

????????
internal?static?ServiceHost?myServiceHost?=?null;


????????
internal?static?void?StartService()

????????
{

???????????????????????

????????????Uri?msqAddress?
=?new?Uri("net.msmq://localhost/private/Indigotest");



???????

????????????myServiceHost?
=?new?ServiceHost(typeof(service1),?msqAddress);

????????????????????

????????????


????????????myServiceHost.Open();

????????}


????????
internal?static?void?StopService()

????????
{

????????????
//?Call?StopService?from?your?shutdown?logic?(i.e.?dispose?method)

????????????if?(myServiceHost.State?!=?CommunicationState.Closed)

????????????????myServiceHost.Close();

????????}


????????
public?static?void?Main()

????????
{

?????????????StartService();

????????????System.Console.ReadLine();

????????}

????}

所以这时候我的servie 的endpoint就是net.msmq://localhost/private/Indigotest

当然跟remoting一样,我定义好了contract,我需要配置一下,哪些contract,哪些service是公布出来的所以配置文件也要写一下.不过这都是自动生成的

<? xml?version="1.0"?encoding="utf-8"? ?>

< configuration >


??
< system .serviceModel >

????
< services >

??????
< service? type ="WinFXServiceLibrary1.service1" > ???????

??????????????
< endpoint? contract ="WinFXServiceLibrary1.IService1" ?binding ="netMsmqBinding" ??? /> ??????????

??????
</ service >

??????

????
</ services >

??
</ system.serviceModel >

</ configuration >

这时候,service就OK了.? 为此我在private队列中,加了一个indigotest队列,并且是事务性的.

这时候,我可以用一些sdk的工具,生成客户端的proxy,就跟以前的wsdl.exe,soapsuds.exe 一样,他又一个svcutil.exe 当然我需要一个基本的httpbinding,跟soapsuds一样.

然后比如svcutil.exe http://localhost:8080/demo?wsdl?,这时候会帮你生成一个配置文件一个一个cs.就是proxy.

Proxy 的代码如下

// ------------------------------------------------------------------------------

// ?<auto-generated>

// ?????This?code?was?generated?by?a?tool.

// ?????Runtime?Version:2.0.50727.42

//

// ?????Changes?to?this?file?may?cause?incorrect?behavior?and?will?be?lost?if

// ?????the?code?is?regenerated.

// ?</auto-generated>

// ------------------------------------------------------------------------------




[System.ServiceModel.ServiceContractAttribute()]

public ? interface ?IService1

{

????

????[System.ServiceModel.OperationContractAttribute(Action
="http://tempuri.org/IService1/MyOperation1",IsOneWay=true?)]

????
void?MyOperation1(string?myValue);

}


public ? interface ?IService1Channel?:?IService1,?System.ServiceModel.IClientChannel

{

}


public ?partial? class ?Service1Proxy?:?System.ServiceModel.ClientBase < IService1 > ,?IService1

{

????

????
public?Service1Proxy()

????
{

????}

????

????
public?Service1Proxy(string?endpointConfigurationName)?:?

????????????
base(endpointConfigurationName)

????
{

????}

????

????
public?Service1Proxy(string?endpointConfigurationName,?string?remoteAddress)?:?

????????????
base(endpointConfigurationName,?remoteAddress)

????
{

????}

????

????
public?Service1Proxy(string?endpointConfigurationName,?System.ServiceModel.EndpointAddress?remoteAddress)?:?

????????????
base(endpointConfigurationName,?remoteAddress)

????
{

????}

????

????
public?Service1Proxy(System.ServiceModel.Binding?binding,?System.ServiceModel.EndpointAddress?remoteAddress)?:?

????????????
base(binding,?remoteAddress)

????
{

????}

????

????
public?void??MyOperation1(string?myValue)

????
{

??????????
base.InnerProxy.MyOperation1(myValue);

????}

}


这个Proxy 其实没有跟service Share Class,而是通过他的Contract 生成了一个代理类.

当然需要有配置文件来配置客户端跟服务端的通讯协议,假设是消息队列,比如重试的机制,可靠传递的机制,要不要事务等.

看一下我的很简单,只是记录了一下我的service 地址

<? xml?version="1.0"?encoding="utf-8" ?>

< configuration >

??
< system .serviceModel >

????
< client >

??????
< endpoint? address ="net.msmq://localhost/private/IndigoTest" ?bindingConfiguration ="msmq"

??????????binding
="netMsmqBinding" ?contract ="IService1" ? >

????????
< identity >

??????????
< userPrincipalName? value ="montaqueDemo" ? />

????????
</ identity >

??????
</ endpoint >

????
</ client >

????
< bindings >

?????

??????
< netMsmqBinding >

????????
< binding? name ="msmq" >

??????????
< security? mode? ="None" />

????????
</ binding >

??????
</ netMsmqBinding >

????
</ bindings >

??
</ system.serviceModel >

</ configuration >



然后调用就很简单了

?

? new ?Service1Proxy().MyOperation1( " haha " );
这个时候,一旦Service Down了,会自动发到对应的msmq队列中,online之后自动继续. 没有一句代码访问msmq,可是已经有了msmq的功能.呵呵.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读