基於介面的呼叫遠比基於基礎訊息互動來得更簡單和便於維護,特別在業務展現上,介面作為業務表現更適合其便利性。為了讓SmartRoute更適合業務應用整合,在新的一年開始SmartRoute整合了遠端介面呼叫功能。基於SmartRoute的基礎特性,在這基礎上擴充套件的介面呼叫會變得更簡單靈活,其特別點如下:並不需要知道服務地址,只需要明確介面和方法即可以實現遠端服務呼叫;無需任何配置即可實現負載和故障遷移。而這一系列的更利功能都歸功於SmartRoute基礎建設!
SmartRoute的遠端介面呼叫是基於Protobuf的RPC實現,其制定服務是以介面為基礎有點似於wcf,但調會變得更透明簡單.以下針對元件實現一個簡單的遠端介面呼叫和負載處理。
介面定義
元件對介面的定義並沒有什麼特別要求或新增特性,但介面方法的定義不支援同名稱過載,現有版本的元件暫不支援。對於out和ref型別的引數也暫不支援。以下是定義一個簡單的使用者操作介面:
public interface IUserService { DateTime Register(string name, string email); void ChangePWD(string name, string oldpwd, string newpwd); }
註冊口服務
介面定義後需要針對介面進行實現才能註冊到服務中,元件是通過SwitchSubscriber來掛載介面服務;首先是初始化通訊節點,然後在這節點服務基礎上構建相應的SwitchSubscriber訂閱器,基於訂閱器即可以進行服務註冊。
public class Program : IUserService { public static void Main(string[] args) { INode node = SmartRoute.NodeFactory.Default; node.Loger.Type = LogType.ALL; node.AddLogHandler(new SmartRoute.ConsoleLogHandler(LogType.ALL)); node.Open(); SwitchSubscriber rmiserver = new SwitchSubscriber(node); rmiserver.Register<IUserService>(new Program()); System.Threading.Thread.Sleep(-1); } public void ChangePWD(string name, string oldpwd, string newpwd) { Console.WriteLine("ChangePWD {0}/{1}/{2}", name, oldpwd, newpwd); } public DateTime Register(string name, string email) { Console.WriteLine("register {0}/{1}", name, email); return DateTime.Now; } }
對於以上服務註冊程式碼相信有朋友會感覺奇怪,為什麼沒有繫結服務地址類似的程式碼?其實這也是元件的特點之一,在整個通訊應用過程中都不需要了解服務地址這一概念,通訊所需要的要求在元件中都完全被透明化了。
呼叫實現
基於服務的呼叫也是在SwitchSubscriber的基礎上進行處理,由於元件暫沒實現介面代理的動態實現,所以現階段只能通過手動實現介面的代理類了。
public class UserService : IUserService { public UserService(SwitchSubscriber context) { this.Context = context; } public SwitchSubscriber Context { get; set; } public void ChangePWD(string name, string oldpwd, string newpwd) { Context.MethodInvoke("IUserService", "ChangePWD", name, oldpwd, newpwd); } public DateTime Register(string name, string email) { return Context.MethodInvoke<DateTime>("IUserService", "Register", name, email); } }
介面的實現通過SwitchSubscriber呼叫相關介面方法名稱傳入相關引數即可,由於元件並不需要知道通訊細節所以也不需要指定介面服務地址的工作。呼叫和服務處理一樣定義節點並開啟構建相關SwitchSubscriber物件即可使用。
INode node = NodeFactory.Default; node.Loger.Type = LogType.ALL; node.AddLogHandler(new ConsoleLogHandler(LogType.ALL)); node.Open(); SwitchSubscriber rmiserver = new SwitchSubscriber(node); mUserService = new UserService(rmiserver); DateTime result = mUserService.Register("henry" + i, "hrenyfan@msn.com"); Console.WriteLine(result);
實際應用效果截圖
負載和遷移
在實際應用中服務必須存在負載和故障遷移,如何為介面服務新增這些功能複雜嗎?由於元件基礎已經整合了這些功能,所以在程式碼上並不需要任何呼叫就能實現多節點負載和故障處理;只要編寫的服務啟動一個新的服務,呼叫者就會自動發現並進行負載呼叫;同樣如果一個節點現出通訊異常後,呼叫者會自動路由到正常的節點服務中。這一系列的措施都是全自動並不需要配置或程式碼來處理!
[瞭解詳情元件開源地址:https://github.com/IKende/SmartRoute]