一、遠程通訊協議的基本原理
網絡通信需要做的就是將流從一台計算機傳輸到另外一台計算機,基於傳輸協議和網絡 IO 來實現,其中傳輸協議比較出名的有 http 、 tcp 、 udp 等等, http 、 tcp 、 udp 都是在基於 Socket 概念上為某類應用場景而擴展出的傳輸協議,網絡 IO ,主要有 bio 、 nio 、 aio 三種方式,所有的分布式應用通訊都基於這個原理而實現,只是為了應用的易用,各種語言通常都會提供一些更為貼近應用易用的應用層協議。
二、應用級協議Binary-RPC
Binary-RPC(Remote Procedure Call Protocol,遠程過程調用協議)是一種和RMI(Remote Method Invocation,遠程方法調用)類似的遠程調用的協議,它和RMI 的不同之處在於它以標准的二進制格式來定義請求的信息 ( 請求的對象、方法、參數等 ) ,這樣的好處是什么呢,就是在跨語言通訊的時候也可以使用。
Binary -RPC 協議的一次遠程通信過程:
1 、客戶端發起請求,按照 Binary -RPC 協議將請求信息進行填充;
2 、填充完畢后將二進制格式文件轉化為流,通過傳輸協議進行傳輸;
3 、接收到在接收到流后轉換為二進制格式文件,按照 Binary -RPC 協議獲取請求的信息並進行處理;
4 、處理完畢后將結果按照 Binary -RPC 協議寫入二進制格式文件中並返回。
問題總結:
1 、傳輸的標准格式是:標准格式的二進制文件。
2 、怎么樣將請求轉化為傳輸的流?將二進制格式文件轉化為流。
3 、怎么接收和處理流?通過監聽的端口獲取到請求的流,轉化為二進制文件,根據協議獲取請求的信息,進行處理並將結果寫入 XML 中返回。
4 、傳輸協議是?http
三、Hessian介紹
Hessian是一個輕量級的remoting on http工具,采用的是Binary RPC協議,所以它很適合於發送二進制數據,同時又具有防火牆穿透能力。Hessian一般是通過Web應用來提供服務,因此非常類似於平時我們用的 WebService。只是它不使用SOAP協議,但相比webservice而言更簡單、快捷。
Hessian官網:http://hessian.caucho.com/
Hessian 可通過Servlet提供遠程服務,需要將匹配某個模式的請求映射到Hessian服務。也可Spring框架整合,通過它的 DispatcherServlet可以完成該功能,DispatcherServlet可將匹配模式的請求轉發到Hessian服務。Hessian的server端提供一個servlet基類, 用來處理發送的請求,而Hessian的這個遠程過程調用,完全使用動態代理來實現的,,建議采用面向接口編程,Hessian服務通過接口暴露。
Hessian處理過程示意圖:客戶端——>序列化寫到輸出流——>遠程方法(服務器端)——>序列化寫到輸出流 ——>客戶端讀取輸入流——>輸出結果
四、Hessian入門范例
4.1下載Hessian
去Hessian官網:http://hessian.caucho.com/下載最新的Hessian包,如下圖所示:
下載完成之后,得到如下圖所示的jar文件
4.2、搭建Hessian測試服務端web項目
新建一個名為HessianServer的web project。將hessian-4.0.37.jar放入WEB-INF/lib文件夾中,如下圖所示:
在進行基於Hessian的項目開發時,應當注意以下幾點:
JAVA服務器端必須具備以下幾點:
- 包含Hessian的jar包。
- 設計一個接口,用來給客戶端調用。
- 實現該接口的功能。
- 配置web.xml,配好相應的servlet。
- 對象必須實現Serializable 接口。
- 對於復雜對像可以使用Map的方法傳遞。
客戶端必須具備以下幾點:
- java客戶端包含Hessian.jar的包。
- 具有和服務器端結構一樣的接口。
- 利用HessianProxyFactory調用遠程接口。
4.3、設計一個提供服務接口來給客戶端調用
IService接口的代碼如下:
1 package gacl.hessian.service; 2 3 import gacl.hessian.model.User; 4 5 /** 6 * <p>ClassName: IService<p> 7 * <p>Description: 定義對外提供服務的接口<p> 8 * @author xudp 9 * @version 1.0 V 10 * @createTime 2014-8-7 下午05:29:23 11 */ 12 public interface IService { 13 14 /** 15 * MethodName: getUser 16 * Description: 獲取用戶 17 * @author xudp 18 * @return User對象 19 */ 20 public User getUser(); 21 }
IService接口中用到了一個User類
User類的代碼如下:
1 package gacl.hessian.model; 2 3 import java.io.Serializable; 4 5 /** 6 * <p>ClassName: User<p> 7 * <p>Description: 創建一個User類,實現序列化接口, 8 * User實現了序列化接口后就可以進行序列化, 9 * 然后就可以通過網絡將序列化后的user傳輸到另一台計算機上<p> 10 * @author xudp 11 * @version 1.0 V 12 * @createTime 2014-8-7 下午05:25:09 13 */ 14 public class User implements Serializable{ 15 16 private static final long serialVersionUID = 1692800630322115854L; 17 //name屬性 18 private String name; 19 20 public User() { 21 22 } 23 24 public User(String name) { 25 this.name = name; 26 } 27 28 public String getName() { 29 return name; 30 } 31 32 public void setName(String name) { 33 this.name = name; 34 } 35 36 37 }
4.4、編寫IService接口的具體實現類
ServiceImpl實現類的代碼如下:
1 package gacl.hessian.service.impl; 2 3 import gacl.hessian.model.User; 4 import gacl.hessian.service.IService; 5 6 /** 7 * <p>ClassName: ServiceImpl<p> 8 * <p>Description: IService接口的具體實現類<p> 9 * @author xudp 10 * @version 1.0 V 11 * @createTime 2014-8-7 下午05:32:15 12 */ 13 public class ServiceImpl implements IService { 14 15 /* (non-Javadoc) 16 * @MethodName getUser 17 * @Description 實現IService接口的getUser方法 18 * @author xudp 19 * @return 返回一個User對象 20 * @see gacl.hessian.service.IService#getUser() 21 */ 22 public User getUser() { 23 return new User("孤傲蒼狼"); 24 } 25 }
4.5、配置web.xml,添加對HessianServlet的配置
如下面的紅色部分所示:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 6 <welcome-file-list> 7 <welcome-file>index.jsp</welcome-file> 8 </welcome-file-list> 9 10 <servlet> 11 <!-- 配置 HessianServlet,Servlet的名字隨便配置,例如這里配置成ServiceServlet--> 12 <servlet-name>ServiceServlet</servlet-name> 13 <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> 14 15 <!-- 配置接口的具體實現類 --> 16 <init-param> 17 <param-name>service-class</param-name> 18 <param-value>gacl.hessian.service.impl.ServiceImpl</param-value> 19 </init-param> 20 </servlet> 21 <!-- 映射 HessianServlet的訪問URL地址--> 22 <servlet-mapping> 23 <servlet-name>ServiceServlet</servlet-name> 24 <url-pattern>/ServiceServlet</url-pattern> 25 </servlet-mapping> 26 27 </web-app>
到此,Hessian的服務端編寫就算是完成了。
配置完成之后,啟動項目,在地址欄輸入:http://localhost:端口號/項目名/ServiceServlet,如果顯示結果如下,說明配置和接口編寫正確:
Hessian Requires POST
4.6、編寫Hessian的測試客戶端
新建一個HessianTestClient的普通Java項目作為測試客戶端,需引入上述的hessian-4.0.37.jar,還需要服務端導出IService和User兩個類的jar,放入lib。或創建兩個一摸一樣的類,這里是采用將服務端的IService和User兩個類打包成jar包提供給客戶端進行調用,打成Jar包的過程如下圖所示:
選中要打包的類
這樣就將IService類和User類打包成了一個Hessian_Common.jar包,如下圖所示:
創建好的HessianTestClient工程如下所示:
HessianTestClient項目引入上述的hessian-4.0.37.jar和IService和User兩個類的jar,編寫HessianClient客戶端,HessianClient類的代碼如下所示:
1 package hessian.test.client; 2 3 import java.net.MalformedURLException; 4 5 import gacl.hessian.model.User; 6 import gacl.hessian.service.IService; 7 8 import com.caucho.hessian.client.HessianProxyFactory; 9 10 /** 11 * <p>ClassName: HessianClient<p> 12 * <p>Description: 調用Hessian的客戶端<p> 13 * @author xudp 14 * @version 1.0 V 15 * @createTime 2014-8-7 下午07:05:42 16 */ 17 public class HessianClient { 18 19 public static void main(String[] args) throws MalformedURLException { 20 /* 21 <servlet> 22 <!-- 配置 HessianServlet,Servlet的名字隨便配置,例如這里配置成ServiceServlet--> 23 <servlet-name>ServiceServlet</servlet-name> 24 <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> 25 26 <!-- 配置接口的具體實現類 --> 27 <init-param> 28 <param-name>service-class</param-name> 29 <param-value>gacl.hessian.service.impl.ServiceImpl</param-value> 30 </init-param> 31 </servlet> 32 <!-- 映射 HessianServlet的訪問URL地址--> 33 <servlet-mapping> 34 <servlet-name>ServiceServlet</servlet-name> 35 <url-pattern>/ServiceServlet</url-pattern> 36 </servlet-mapping> 37 */ 38 //在服務器端的web.xml文件中配置的HessianServlet映射的訪問URL地址 39 String url = "http://192.168.1.144:8080/HessianServer/ServiceServlet"; 40 HessianProxyFactory factory = new HessianProxyFactory(); 41 IService service = (IService) factory.create(IService.class, url);//創建IService接口的實例對象 42 User user = service.getUser();//調用Hessian服務器端的ServiceImpl類中的getUser方法來獲取一個User對象 43 System.out.println(user.getName()); 44 } 45 }
將HessianServer項目部署到tomcat服務器,啟動tomcat服務器,然后運行HessianClient客戶端,運行結果如下:
從運行結果中可以看到,在HessianClient客戶端中已經成功獲取到遠程的HessianServer服務器端傳輸過來的User對象,然后打印出User對象的名字。
以上就是Hessian的一個入門級別的案例!
4.7、測試項目下載
Hessian服務端:HessianServer,Hessian測試客戶端:HessianTestClient