亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

rpc通信是如何進行的

發布時間:2022-01-18 10:10:15 來源:億速云 閱讀:177 作者:iii 欄目:大數據

這篇文章主要介紹了rpc通信是如何進行的的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇rpc通信是如何進行的文章都會有所收獲,下面我們一起來看看吧。

RPC(Remote Procedure Call Protocol)——遠程過程調用協議,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。該協議允許運行于一臺計算機的程序調用另一臺計算機的子程序,而程序員無需額外地為這個交互作用編程。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通信程序之間攜帶信息數據。在OSI網絡通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分布式多程序在內的應用程序更加容易。

基本概念

  • RPC(Remote Procedure Call)遠程過程調用,簡單的理解是一個節點請求另一個節點提供的服務

  • 本地過程調用:如果需要將本地student對象的age+1,可以實現一個addAge()方法,將student對象傳入,對年齡進行更新之后返回即可,本地方法調用的函數體通過函數指針來指定。

  • 遠程過程調用:上述操作的過程中,如果addAge()這個方法在服務端,執行函數的函數體在遠程機器上,如何告訴機器需要調用這個方法呢?

今天,我們就通過一個實例代碼進行演示,一步步的查看,rpc的通信是如何進行的,有興趣的朋友可以把代碼進行實現,自己debug一下,查看每一步的傳參

package com.mashibing.rpc.common;

import java.io.Serializable;

public class User implements Serializable {
   private static final long serialVersionUID = 1L;

   private Integer id;
   private String name;

   public User(Integer id, String name) {
       this.id = id;
       this.name = name;
   }

   public Integer getId() {
       return id;
   }

   public String getName() {
       return name;
   }

   public void setId(Integer id) {
       this.id = id;
   }

   public void setName(String name) {
       this.name = name;
   }

   @Override
   public String toString() {
       return "User{" +
               "id=" + id +
               ", name='" + name + '\'' +
               '}';
   }
}
package com.mashibing.rpc.common;

public interface IUserService {
   public User findUserById(Integer id);
}
package com.mashibing.rpc01;


import com.mashibing.rpc.common.IUserService;
import com.mashibing.rpc.common.User;

public class UserServiceImpl implements IUserService {
   @Override
   public User findUserById(Integer id) {
       return new User(id, "Alice");
   }
}
package com.mashibing.rpc01;

import com.mashibing.rpc.common.User;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

public class Client {
   public static void main(String[] args) throws Exception {
       Socket s = new Socket("127.0.0.1", 8888);
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       DataOutputStream dos = new DataOutputStream(baos);
       dos.writeInt(123);

       s.getOutputStream().write(baos.toByteArray());
       s.getOutputStream().flush();

       DataInputStream dis = new DataInputStream(s.getInputStream());
       int id = dis.readInt();
       String name = dis.readUTF();
       User user = new User(id, name);

       System.out.println(user);

       dos.close();
       s.close();
   }
}
package com.mashibing.rpc02;

import com.mashibing.rpc.common.User;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

public class Stub {
   public User findUserById(Integer id) throws Exception {
       Socket s = new Socket("127.0.0.1", 8888);
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       DataOutputStream dos = new DataOutputStream(baos);
       dos.writeInt(123);

       s.getOutputStream().write(baos.toByteArray());
       s.getOutputStream().flush();

       DataInputStream dis = new DataInputStream(s.getInputStream());
       int receivedId = dis.readInt();
       String name = dis.readUTF();
       User user = new User(id, name);

       dos.close();
       s.close();
       return user;
   }
}
package com.mashibing.rpc03;

import com.mashibing.rpc.common.IUserService;
import com.mashibing.rpc.common.User;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

/**
* 而且Client的調用顯得不是很合理(Stub里只有findById的代碼),如果有個findByName的新方法,那么就又得重新改進
* 下面這種寫法解決了方法增加的問題
*/

public class Stub {
   public static IUserService getStub() {
       InvocationHandler h = new InvocationHandler() {
           @Override
           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               Socket s = new Socket("127.0.0.1", 8888);

               ByteArrayOutputStream baos = new ByteArrayOutputStream();
               DataOutputStream dos = new DataOutputStream(baos);
               dos.writeInt(123);

               s.getOutputStream().write(baos.toByteArray());
               s.getOutputStream().flush();

               DataInputStream dis = new DataInputStream(s.getInputStream());
               int id = dis.readInt();
               String name = dis.readUTF();
               User user = new User(id, name);

               dos.close();
               s.close();
               return user;
           }
       };
       Object o = Proxy.newProxyInstance(IUserService.class.getClassLoader(), new Class[] {IUserService.class}, h);
       return (IUserService)o;
   }
}
package com.mashibing.rpc04;

import com.mashibing.rpc.common.IUserService;
import com.mashibing.rpc.common.User;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

/**
* 但是這里僅僅實現了findByUserId的方法代理,如果要實現其他方法的代理該怎么做呢?
* 這里就要從協議層做出改進
*
* 服務器端也要做出對應處理
*/

public class Stub {
   public static IUserService getStub() {
       InvocationHandler h = new InvocationHandler() {
           @Override
           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               Socket s = new Socket("127.0.0.1", 8888);

               ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());

               String methodName = method.getName();
               Class[] parametersTypes = method.getParameterTypes();
               oos.writeUTF(methodName);
               oos.writeObject(parametersTypes);
               oos.writeObject(args);
               oos.flush();


               DataInputStream dis = new DataInputStream(s.getInputStream());
               int id = dis.readInt();
               String name = dis.readUTF();
               User user = new User(id, name);

               oos.close();
               s.close();
               return user;
           }
       };
       Object o = Proxy.newProxyInstance(IUserService.class.getClassLoader(), new Class[] {IUserService.class}, h);
       return (IUserService)o;
   }




}
package com.mashibing.rpc04;

import com.mashibing.rpc.common.IUserService;
import com.mashibing.rpc.common.User;

import java.io.*;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
   private static boolean running = true;
   public static void main(String[] args) throws Exception {
       ServerSocket ss = new ServerSocket(8888);
       while (running) {
           Socket s = ss.accept();
           process(s);
           s.close();
       }
       ss.close();
   }

   private static void process(Socket s) throws Exception {
       InputStream in = s.getInputStream();
       OutputStream out = s.getOutputStream();
       ObjectInputStream oos = new ObjectInputStream(in);
       DataOutputStream dos = new DataOutputStream(out);

       String methodName = oos.readUTF();
       Class[] parameterTypes = (Class[])oos.readObject();
       Object[] args = (Object[])oos.readObject();

       IUserService service = new UserServiceImpl();
       Method method = service.getClass().getMethod(methodName, parameterTypes);
       User user = (User)method.invoke(service, args);



       dos.writeInt(user.getId());
       dos.writeUTF(user.getName());
       dos.flush();
   }
}

返回值用Object封裝,支持任意類型

關于“rpc通信是如何進行的”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“rpc通信是如何進行的”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

rpc
AI

阳西县| 从江县| 九寨沟县| 松桃| 吴旗县| 乌拉特中旗| 荔浦县| 鸡泽县| 永仁县| 景泰县| 慈溪市| 沅江市| 修文县| 黔江区| 咸宁市| 桂东县| 依兰县| 卢龙县| 息烽县| 屯昌县| 衡山县| 铅山县| 桓仁| 黎平县| 赣榆县| 新源县| 古蔺县| 深泽县| 竹山县| 乡城县| 丰镇市| 邳州市| 绵竹市| 刚察县| 正定县| 星子县| 织金县| 大渡口区| 肃北| 调兵山市| 定陶县|