美文网首页.NET
WCF服务使用ProtoBuf传输

WCF服务使用ProtoBuf传输

作者: 凌雲木 | 来源:发表于2017-08-23 21:23 被阅读78次

ProtoBuf的优缺点不再叙说,本篇主要介绍是WCF服务端和WCF客户端通过ProtoBuf传输数据的例子。

1 数据流:
image.png
2 WCF服务端:
  • 2.1 需要在项目引入protobuf-net
  • 2.2 创建需要在服务中需要传递的类型UserInfoWCF服务把它序列化为ProtoBuf
    二进制数据传到客户端,供客户端调用并解析为UserInfo类。注意服务端和客户端使用的UserInfo类必须一样,这样才能解析出来。
    UserInfo类:
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FG_WCFServer
{
    /// <summary>
    /// 用户信息类
    /// </summary>
    [ProtoContract]
    public class UserInfo 
    {
        /// <summary>
        /// 用户编号
        /// </summary>
        [ProtoMember(1)]
        public int ID { get; set; }
        /// <summary>
        /// 账号
        /// </summary>
        [ProtoMember(2)]
        public string UserAccount { get; set; }
        /// <summary>
        /// 密码
        /// </summary>
        [ProtoMember(3)]
        public string UserPassWord { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        [ProtoMember(4)]
        public string UserName { get; set; }
        /// <summary>
        /// 性别
        /// </summary>
        [ProtoMember(5)]
        public string UserSex { get; set; }
        /// <summary>
        /// 职位
        /// </summary>
        [ProtoMember(6)]
        public string UserOffice { get; set; }
        /// <summary>
        /// 联系方式
        /// </summary>
        [ProtoMember(7)]
        public string UserPhone { get; set; }
        /// <summary>
        /// 邮箱
        /// </summary>
        [ProtoMember(8)]
        public string UserEmail { get; set; }
        /// <summary>
        /// 角色
        /// </summary>
        [ProtoMember(9)]
        public int UserCharacter { get; set; }
        /// <summary>
        /// 所属工厂编号
        /// </summary>
        [ProtoMember(10)]
        public int UserFactoryNum { get; set; }
        /// <summary>
        /// 上次登录时间
        /// </summary>
        [ProtoMember(11)]
        public DateTime UserLastLoginTime { get; set; }
    }
}

  • 2.3 封装ProtoBuf序列化方法
 /// <summary>
    /// ProtoBuf序列化类用于序列化及解析数据
    /// </summary>
    public class SerializBaseModel
    {
        /// <summary>
        /// 序列化类型数据
        /// </summary>
        /// <returns></returns>
        public static byte[] SerializeModel<T>(T model)where T:new ()
        {
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    Serializer.Serialize(ms, model);
                    ms.Position = 0;
                    return ms.ToArray();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 反序列化类型数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array"></param>
        /// <returns></returns>
        public static T DeSerialize<T>(byte[] array) where T : new()
        {
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    ms.Write(array, 0, array.Length);
                    ms.Position = 0;
                    return Serializer.Deserialize<T>(ms);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
  • 2.4 创建WCF服务需要的接口 IUserManagement
using FG_Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace FG_WCFServer
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IUserManagement”。
    [ServiceContract]
    public interface IUserManagement
    {
        [OperationContract]
        string DoWork();
        [OperationContract]
        List<byte[]> GetUserInfoALL();
    }
}

  • 2.5创建实现接口的类 UserManagement
using FG_DAL;
using FG_Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace FG_WCFServer
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“UserManagement”。
    public class UserManagement : IUserManagement
    {
        public string DoWork()
        {
            return "WCF Server OK";
        }
        /// <summary>
        /// 获取所有用户信息数据
        /// </summary>
        /// <returns></returns>
        public List<byte[]> GetUserInfoALL()
        {
            UserManagementDal dal = new UserManagementDal();//数据解析层
            List<UserInfo> list = dal.GetAllUserInfo();//获取MySql数据
            List<byte[]> bytelist = new List<byte[]>();
            foreach (var item in list)
            {
                //集合每一项序列化为ProtoBuf二级制数据
                bytelist.Add(item.SerializeModel());
            }     
            return bytelist;
        }
    }
}
  • 2.6 WCF配置
 <system.serviceModel>
    <services>
      <!--用户服务-->
      <service name="FG_WCFServer.UserManagement">
        <endpoint address="" binding="basicHttpBinding" contract="FG_WCFServer.IUserManagement" bindingConfiguration="BigBufferSendBinding">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>       
            <add baseAddress="http://localhost:8733/Design_Time_Addresses/FG_WCFServer/UserManagement/" />
          </baseAddresses>
        </host>
      </service>   
    </services>
    <bindings>
      <basicHttpBinding>
        <binding name="BigBufferSendBinding" maxReceivedMessageSize="2147483647" messageEncoding="Text" transferMode="Streamed" sendTimeout="00:00:20">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- 为避免泄漏元数据信息,
          请在部署前将以下值设置为 false -->
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
          <!-- 要接收故障异常详细信息以进行调试,
          请将以下值设置为 true。在部署前设置为 false 
          以避免泄漏异常信息 -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  • 2.7WCF服务初始化:
static void Main(string[] args)
        {
            ServiceHost wcfhost = new ServiceHost(typeof(FG_WCFServer.UserManagement));
            wcfhost.Open();
            Console.WriteLine("服务已启动");
            Console.ReadKey();
        }
3 客户端:
  • 3.1 创建控制台项目, 引入wcf服务
  • 3.2 同服务端需要引入protobuf-net,创建UserInfo类及数据解析ProtoBuf序列化方法(同服务端)
  • 3.3 修改控制台Main方法
  static void Main(string[] args)
        {          
            ServiceReference1.UserManagementClient client = new ServiceReference1.UserManagementClient();
            var arraylist = client.GetUserInfoALL().ToList();
            List<UserInfo> list = new List<UserInfo>();
            foreach (var item in arraylist)
            {                
                list.Add(SerializBaseModel.DeSerialize<UserInfo>(item));
            }
            foreach (var item in list)
            {
                Console.WriteLine($"账号:{item.UserAccount}  姓名:{item.UserName}");
            }        
            Console.ReadKey();
        }
4 结果:
image.png

相关文章

网友评论

    本文标题: WCF服务使用ProtoBuf传输

    本文链接:https://www.haomeiwen.com/subject/tpbldxtx.html