注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[.NET] Hello WCF  

2012-01-29 18:09:35|  分类: win32 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
WCF定义了一套RPC规范。其中 Contacts, Binding, Address 三者,决定了一个完整的 Service Provider。
Contacts,接口描述(what),决定了所传递的数据的格式,比如 SOAP、JSON。
Binding,传输层协议(how),比如 http, tcp。
Address,服务提供的地点(where),比如 http://localhost:8000/Order。
其实 binding/address 有时是分不开的,比如 0mq 通过 tcp://xxx, inproc://xxx 同时决定了 binding/address

速度上代码,代码流~
.net/mono都能编译、运行。:-)

传递的数据格式,SOAP Message
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
  <s:Header>
    <wsa:Action s:mustUnderstand="1">urn:SubmitOrder</wsa:Action>
    <wsa:MessageID>4</wsa:MessageID>
    <wsa:ReplyTo>
      <wsa:Address> http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
      </wsa:Address>
    </wsa:ReplyTo>
    <wsa:To s:mustUnderstand="1">http://localhost:8000/Order</wsa:To>
  </s:Header>
  <s:Body>
    <Order>
      <ProdID>6</ProdID>
      <Qty>6</Qty>
      <Status>order placed</Status>
    </Order>
  </s:Body>
</s:Envelope>

Contracts.cs 是接口描述
Receiver.cs 是接口实现,消息接受者、消息处理
ReceiverHost.cs 是 simple self-host,注意要用管理员权限来运行
Sender.cs 是消息发送者

---------------------------- Contracts.cs ----------------------------
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

[ServiceContract(Namespace="http://wintellect.com/ProcessOrder")]
public interface IProcessOrder
{
    [OperationContract(Action="urn:SubmitOrder")]
    void SubmitOrder(Message order);
}
---------------------------- Receiver.cs ----------------------------
using System;
using System.Xml;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;

public sealed class MyService : IProcessOrder
{
    public void SubmitOrder(Message order)
    {
        String fileName = "Order" + order.Headers.MessageId.ToString() + ".xml";
        Console.WriteLine("Message ID {0} received", order.Headers.MessageId.ToString());

        XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(new FileStream(fileName, FileMode.Create));
        order.WriteMessage(writer);
        writer.Close();
    }
}
---------------------------- ReceiverHost.cs ----------------------------
using System;
using System.Xml;
using System.ServiceModel;

internal static class ReceiverHost
{
    public static void Main()
    {
        WSHttpBinding binding = new WSHttpBinding(SecurityMode.None);
        binding.MessageEncoding = WSMessageEncoding.Text;

        Uri addressURI = new Uri(@"http://localhost:8000/Order");

        ServiceHost svc = new ServiceHost(typeof(MyService));
        svc.AddServiceEndpoint(typeof(IProcessOrder), binding, addressURI);
        svc.Open();

        Console.WriteLine("The receiver is ready");
        Console.ReadLine();

        svc.Close();
    }
}
---------------------------- Sender.cs ----------------------------
using System;
using System.Text;
using System.Xml;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.IO;
using System.ServiceModel.Channels;

public static class Sender
{
    public static void Main()
    {
        Console.WriteLine("Press ENTER when the receiver is ready");
        Console.ReadLine();

        EndpointAddress address = new EndpointAddress(@"http://localhost:8000/Order");
    
        WSHttpBinding binding = new WSHttpBinding(SecurityMode.None);
        binding.MessageEncoding = WSMessageEncoding.Text;
    
        ChannelFactory<IProcessOrder> channel = new ChannelFactory<IProcessOrder>(binding, address);
        IProcessOrder proxy = channel.CreateChannel();
    
        Message msg = null;
        for (int i = 0; i < 20; i++)
        {
            msg = GenerateMessage(i, i);
    
            UniqueId uniqueId = new UniqueId(i.ToString());
            msg.Headers.MessageId = uniqueId;
    
            Console.WriteLine("Sending Message #{0}", uniqueId.ToString());
    
            msg.Headers.Action = "urn:SubmitOrder";
            proxy.SubmitOrder(msg);
        }
    }

    private static Message GenerateMessage(int productID, int qty)
    {
        MemoryStream stream = new MemoryStream();

        XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false);
        writer.WriteStartElement("Order");
        writer.WriteElementString("ProdID", productID.ToString());
        writer.WriteElementString("Qty", qty.ToString());
        writer.WriteEndElement();

        writer.Flush();
        stream.Position = 0;

        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, XmlDictionaryReaderQuotas.Max);
        return Message.CreateMessage(MessageVersion.Soap12WSAddressing10, String.Empty, reader);
    }
}
-------------------------------------------------------------------
csc Contracts.cs Receiver.cs ReceiverHost.cs
csc Contracts.cs Sender.cs

dmcs /r:System.ServiceModel.dll /r:System.Runtime.Serialization.dll /out:ReceiverHost.exe Contracts.cs Receiver.cs ReceiverHost.cs
dmcs /r:System.ServiceModel.dll /r:System.Runtime.Serialization.dll /out:Sender.exe Contracts.cs Sender.cs
-------------------------------------------------------------------

ps. 从 Vista/2008/Win7 开始,80以外端口,需要administrator权限,如下可以设置某个端口给普通用户使用。
      netsh http add urlacl url=http://+:8002/user="MachineOrDomain\UserName"
  评论这张
 
阅读(1114)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017