基於TCP 協議的RPC


前言:

環境:
    windown 10
    Eclipse
   JDK 1.8
RPC的概念:
    RPC 是遠程過程調用,是分布式網站的基礎。

實驗

SayHelloService.java 接口類,用於規范
SayHelloServiceImpl.java,是SayHelloService 的實現類
Provider.java 是服務的提供類
Consumer.java 是服務的消費類

SayHelloService.java

package cn.szxy;

/**
 * 接口
 *
 */
public interface SayHelloService {
	/**
	 * 返回一個字符串
	 * @param str
	 * @return
	 */
	public String sayHello(String str);
}


SayHelloServiceImpl.java

package cn.szxy;

/**
 * 實現類
 *
 */
public class SayHelloServiceImpl implements SayHelloService{

	@Override
	public String sayHello(String str) {
		if(str.equals("Hello")){
			return "Hello 你好";
		}else{
			return "byebye!";
		}
	}
	
}


服務提供類 Provider.java


package cn.szxy;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

/**
 *  
 * 基於TCP協議的 服務提供端
 * 
 */
public class Provider{
	
	public static void main(String[] args) throws Exception {
		HashMap<Object, Object> map = new HashMap<>();
		map.put(SayHelloService.class.getName(), new SayHelloServiceImpl());
		
		
		//創建 socket 對象
		ServerSocket server = new ServerSocket(5555);
		System.out.println("服務器已啟動....");
		while(true){
			
			//監聽用戶請求
			Socket client = server.accept();
			//獲取輸入流
			ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
			
			String inferName = ois.readUTF();
			String methodName = ois.readUTF();
			Class<?>[] parameterTypes = (Class<?>[]) ois.readObject();
			Object[] arguments = (Object[])ois.readObject();
			
			//執行調用 
			Class<?> serviceClass = Class.forName(inferName);
			Object service = map.get(inferName);
			Method method = serviceClass.getMethod(methodName, parameterTypes);
			//執行方法,並返回結果
			Object result = method.invoke(service, arguments);
			
			System.out.println("要發送處理的結果: "+result);
			
			
			//獲取輸出流
			ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
			oos.writeObject(result);
			oos.writeUTF("調用結束");
			oos.flush();
			;
		}
	}
}

服務消費類 Consumer

package cn.szxy;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Scanner;
/**
 * 
 *   基於 TCP的服務器消費端
 *   
 *  
 */
public class Consumer{
	
	public static void main(String[] args) throws Exception {
			
			//獲取需要發送的東西
			String interName = SayHelloService.class.getName();
			Method method = SayHelloService.class.getMethod("sayHello", String.class);
			Object[]  argurements = {"Hello"};
			
			//創建 socket 對象
			Socket client = new Socket("127.0.0.1",5555);
			//獲取輸出流
			ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
			oos.writeUTF(interName);
			oos.writeUTF(method.getName());
			oos.writeObject(method.getParameterTypes());
			oos.writeObject(argurements);
			
			//刷新緩沖區,不然會出現”連接重置 connection reset 找不到資源 “的問題
			oos.flush();
			
			//獲取輸入流
			ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
			Object result = ois.readObject();
			String str = ois.readUTF();
			System.out.println("RPC遠程調用結果: ");
			System.out.println(result);
			
		
			//關閉連接
			client.close();
	}
}

總結

 RPC 是基於 Java 的Socket的基礎上,利用 socket 和 IO流將服務消費端需要調用的類和類中方法以及方法的參數發送給服務提供端
 服務提供端接受了服務消費端的請求,利用反射技術將對應需要的方法執行並返回結果,發送給服務消費者。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM