离上次发表文章已经挺久的了,wcf这块确实挺烦人的,虽然用过几次,但是手写起来还是有点陌生,看了不少wcf的文章,终少有领悟,这里我捎带提起,更详细的我会推荐几篇不错文章供大家参考。

  首先看下wcf大概包括些什么内容,这里是让大家有个清晰的纲领,不会深入介绍wcf,再说这一块也不是我这个凡人能给大家三言两语就能说明白的。

一步步实现自己的框架系列(三):客户端服务端通信的实现

  要使用wcf通信,首先要定义契约,我们再来看下wcf有哪些契约。

一步步实现自己的框架系列(三):客户端服务端通信的实现

  wcf的四种契约,我给他按使用的优先级拍个序吧,Service Contract是必不可少的也是必须的,Data Contract 也是常会用到的,用来定义通信结构体,但是没有这个,我们使用基础类型也是能完成通信,其次是Fualt Contract通信失败的契约,这个能告诉我们调用失败的详细信息也是很重要的,最后是Message Contract,这个是最不常用的了,本文也不会用到,有兴趣的可以自己找点资料看看。

  好吧,引出我们今天的话题,客户端服务端通信的实现,关于通信设计模型大家可以看我第一篇的介绍,这里就不重复了。不管是客户端调用服务端还是服务端回调客户端,都是方法的调用,无非就是:(请求-回复)或者(请求),既然这样看下我定义的数据契约吧,定义的数据契约包括 请求数据契约 和 响应契约 两种。

    [DataContract(Namespace = "http://www.cnblogs.com/guanglin/", Name = "Request")]
    public class Request
    {
        [DataMember]
        public string InstanceId { get; set; }

        [DataMember]
        public string MethodName { get; set; }

        [DataMember]
        public string[] ParamTypes { get; set; }

        [DataMember]
        public byte[] Parameters { get; set; }

    }

  这个是请求契约其中MethodName为请求调用的方法名称,ParamType为请求调用的参数类型,Parameters为请求调用的参数,这里Parameters为什么使用byte[]数据类型呢?因为我们调用的方法参数的类型是不确定的,这里将参数序列化后传输,使用时再反序列化回来即可。这里还有个InstanceId是干什么用的呢,这跟我们的设计有关,我的客户端与服务端是基于页面创建的,这个InstanceId代表的是请求的页面服务或回调页面的唯一标识。

  接下来看下响应契约,这个就简单了。

    [DataContract(Namespace = "http://www.cnblogs.com/guanglin/", Name = "Response")]
    public class Response
    {
        [DataMember]
        public string InstanceId { get; set; }

        [DataMember]
        public byte[] Value { get; set; }
    }

  回复契约只有唯一标识和返回值,并且返回值也使用byte[]传输,大家也能想到,这里返回值也将使用序列化传输。

  好吧,数据契约定义完成了,下面来看下我们定义的服务契约与回调契约吧。服务契约是客户端调用服务的接口。

服务契约:

   [ServiceContract(CallbackContract=typeof(ICoreCallbackService),
        SessionMode = SessionMode.Required,
        Namespace="GL")]
    public interface ICoreService
    {
        #region 连接操作
        /// <summary>
        /// 连接到服务器,创建Session
        /// </summary>
        /// <param name="clientSessionInfo">客户端连接信息</param>
        /// <returns>连接的SessionId</returns>
        [OperationContract]
        [FaultContract(typeof(GLFaultContract))]
        string Connect(ClientConnectionInfo clientSessionInfo);

        /// <summary>
        /// 重新连接到服务器
        /// </summary>
        /// <param name="sessionId">重新连接的SessionId</param>
        [OperationContract]
        [FaultContract(typeof(GLFaultContract))]
        void Reconnect(string sessionId);

        /// <summary>
        /// 断开与服务器
        /// </summary>
        [OperationContract(IsTerminating = true)]
        [FaultContract(typeof(GLFaultContract))]
        void Disconnect();
        #endregion

        #region 页面操作
        /// <summary>
        /// 创建PageService实例返回实例id
        /// </summary>
        /// <param name="serviceTypeName">serviceTypeName</param>
        /// <returns>instanceId</returns>
        [OperationContract(IsOneWay = false)]
        [FaultContract(typeof(GLFaultContract))]
        string CreatePageService(string serviceTypeName);

        /// <summary>
        /// 销毁PageService实例
        /// </summary>
        /// <param name="instanceId">instanceId</param>
        [OperationContract(IsOneWay = true)]
        void DestoryPageService(string instanceId);

        /// <summary>
        /// 调用一个页面服务方法
        /// </summary>
        /// <param name="request">页面调用请求</param>
        /// <returns>页面调用回复</returns>
        [OperationContract]
        [FaultContract(typeof(GLFaultContract))]
        Response CallPageService(Request request);

        /// <summary>
        /// 单向调用一个页面服务方法
        /// </summary>
        /// <param name="request">页面调用请求</param>
        [OperationContract(IsOneWay = true)]
        void OneWayCallPageService(Request request);

        /// <summary>
        /// 调用Session公共服务
        /// </summary>
        /// <param name="request">服务请求参数</param>
        /// <returns>服务请求回复</returns>
        [OperationContract]
        [FaultContract(typeof(GLFaultContract))]
        Response CallService(Request request);

        /// <summary>
        /// 单向调用Session公共服务
        /// </summary>
        /// <param name="request">服务请求参数</param>
        [OperationContract(IsOneWay = true)]
        void OneWayCallService(Request request);
        #endregion
View Code

相关文章: