用 WCF 实现多层服务架构平台
1、业务层服务。
业务层可以通过连接到“业务适配器”进行注册。将自身的“公共地址”注册给服务层,并且注册自己所对应的“应用程序名”。这有点像这样:
??? /// <summary> 业务服务器的注册信息。
??? /// </summary>
??? [Serializable]
??? public class RegisterInfo
??? {
??????? protected string _BusinessID;
??????? public string BusinessID
??????? {
??????????? get
??????????? {
??????????????? return this._BusinessID;
??????????? }
??????? }
??????? protected string _ApplicationName;
??????? public string ApplicationName
??????? {
??????????? get
??????????? {
??????????????? return this._ApplicationName;
??????????? }
??????? }
??????? protected string _PrivateIP;
??????? public string PrivateIP
??????? {
??????????? get
??????????? {
??????????????? return this._PrivateIP;
??????????? }
??????? }
??????? protected string _PublicIP;
??????? public string PublicIP
??????? {
??????????? get
??????????? {
??????????????? return this._PublicIP;
??????????? }
??????? }
??????? protected string _AddressFormat;
??????? public string AddressFormat
??????? {
??????????? get
??????????? {
??????????????? return this._AddressFormat;
??????????? }
??????? }
??????? public RegisterInfo(string bussineID, string applicationName, string privateIP, string publicIP)
??????? {
??????????? this._BusinessID = bussineID;
??????????? this._ApplicationName = applicationName;
??????????? this._PrivateIP = privateIP;
??????????? this._PublicIP = publicIP;
??????? }
??????? public void SetAddressFormat(string address)
??????? {
??????????? this._AddressFormat = address.Replace("localhost", "{0}");
??????? }
??? }
业务层在向往适配层注册服务时,需要提供自己的“客户层应用程序名”,自己的“内外网地址”。这样,适配层在接收到客户层的申请时,便可以将注册的“连接地址”告诉客户层。
这样做的目的在于:保护实际业务的操作接口(虽然也是公开接口,但是客户端并不知道如何连接他,只能通过账号密码验证后,业务层发送过来的地址,客户端才可以连接)。
当然更重要的是,还可以实现一个应用多个“服务接口”,这样在分布式应用中是最有效缓解服务器压力的方法之一。
业务层需要注册信息已经确认了,那么便是将服务契约(适配层实现)。
??? /// <summary> 注册适配器的契约。
??? /// </summary>
??? [ServiceContract(CallbackContract = typeof(IRegisterCallback))]
??? public interface IRegisterContract
??? {
??????? /// <summary> 将业务服务器注册到适配服务器。
??????? /// </summary>
??????? [OperationContract]
??????? Result Register(RegisterInfo info);
??????? [OperationContract(IsOneWay = true)]
??????? void FromBusinessPing(object arg);
??? }
Callback契约如下(业务层实现):
??? /// <summary> 注册适配器的回调契约。
??? /// </summary>
??? public interface IRegisterCallback
??? {
??????? /// <summary> 当适配器接收登录验证时的回调函数。
??????? /// </summary>
??????? [OperationContract]
??????? Result ClientLogin(string uid, string pwd);
??????? /// <summary> 激活业务服务器的状态。
??????? /// </summary>
??????? [OperationContract(IsOneWay = true)]
??????? void FromAdapterPing(PingCommand command, object arg);
??? }
这两个接口用于业务层与适配层之间的会话。每当有一个新的客户端连接到适配层时,适配层会向其索要登录凭证,然后转发给对应的应用名的业务层。当业务层校验成功,适配层才会将这个“隐藏于公众”的地址抛给客户端。IRegisterContract.FromBusinessPing 是适配层接收到业务层的“激活测试”,业务层要告诉适配层:“我正在运行,可以将客户给我”。IRegisterCallback.FromAdapterPing 也是同样的道理。这样双方互 PING,可以确保业务层和适配层的在线情况。
当然,这么繁琐的“双方互PING”,还有一个更加重要的作用。
??? /// <summary> 表示适配服务器发送至业务服务器的命令。
??? /// </summary>
??? public enum PingCommand
??? {
??????? /// <summary>? 表示这是一个普通的命令。
??????? /// </summary>
??????? None,
??????? /// <summary>? 表示这是一个业务服务器关闭的命令。
??????? /// </summary>
??????? Close,
??????? /// <summary>? 表示这是一个业务服务器更新的命令。使用Hubble.Net实现全文检索
??????? /// </summary>
??????? Update,
??? }
通过上面的代码,园友便可以发现,在互动会话的过程中,可以做到“一方断线,多方支援”。而当业务层分布在10台不同的电脑上,更新业务层也是一个头疼的问题。所以,这个问题可以交给适配层来完成。适配层只要检测到本地“业务层”或“客户层”应用程序有版本变化,便会主动(客户层是被动)通知对方更新要求。这样客户层和业务层的更新便可以完美解决。
至此,业务层与适配层之间的交互,已经简单的告诉大家了。
?
?