写点什么

用远程代理模式轻松实现远程服务调用,打开编程新大门

  • 2025-04-28
    福建
  • 本文字数:3513 字

    阅读完需:约 12 分钟

通过远程代理来实现一个简易的远程过程调用实例。带你打开新的大门。


Socket 远程代理服务案例


基于 Socket 的远程服务,我们需要完成以下步骤:


  1. 服务端实现:创建一个远程服务,通过 Socket 接受客户端请求并提供计算服务。

  2. 客户端实现:客户端通过代理类访问远程计算服务,代理通过网络与服务器交互。

  3. 代理类:代理类会通过网络与服务器建立连接,转发请求并返回响应。


看下案例类图应该就明白了


案例类图



客户端和服务端都共有服务接口RemoteCalculationService,服务端实现了该接口的具体处理逻辑,客户端通过socket来完成具体服务的调用。


在这里必须明确理解的一个点就是,客户端的远程代理类。这个远程代理类是一个实现了共有服务接口RemoteCalculationService的实现类,但是在真实的场景中,这个代理类不需要我们手工动去实现,一般由所依赖的底层去实现(比如Apache CXF),我们要做的事情是配置 IP 和端口等操作,然后调用接口内的方法即可。


客户端在这个过程中只需要关注这个服务接口RemoteCalculationService有什么方法可以使用、具体传什么参数和返回值是什么即可,给开发者的感觉就像是调用本地方法一样


具体代码实现如下:


远程服务接口


我们首先定义一个远程计算服务接口,它提供加法和减法功能:


// 远程接口public interface RemoteCalculationService {    int add(int a, int b);    int subtract(int a, int b);}
复制代码


远程服务实现


然后实现该接口,模拟一个远程计算服务。此服务将被远程调用:


public class RemoteCalculationServiceImpl implements RemoteCalculationService {
@Override public int add(int a, int b) { return a + b; }
@Override public int subtract(int a, int b) { return a - b; }
}
复制代码


远程服务处理器


该类负责处理来自客户端的请求,它从网络中读取数据并返回计算结果:


import java.io.*;import java.net.*;
public class RemoteCalculationServiceHandler implements Runnable { private Socket socket;
public RemoteCalculationServiceHandler(Socket socket) { this.socket = socket; }
@Override public void run() { try ( ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream()); ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream()) ) { // 读取请求的操作 String operation = (String) inputStream.readObject(); int a = inputStream.readInt(); int b = inputStream.readInt();
RemoteCalculationServiceImpl service = new RemoteCalculationServiceImpl(); int result = 0; System.out.println("执行的操作:"+operation); // 根据操作执行相应的计算 if ("add".equals(operation)) { result = service.add(a, b); } else if ("subtract".equals(operation)) { result = service.subtract(a, b); } System.out.println("执行结果:"+result); // 发送结果回客户端 outputStream.writeInt(result); outputStream.flush(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }}
复制代码


远程 Socket 服务


public class RemoteServer {
// 服务器端启动 public static void main(String[] args) { try (ServerSocket serverSocket = new ServerSocket(8080)) { System.out.println("Server is running..."); while (true) { Socket socket = serverSocket.accept(); new Thread(new RemoteCalculationServiceHandler(socket)).start(); } } catch (IOException e) { e.printStackTrace(); } }}
复制代码


远程服务代理类


代理类负责与远程服务通信。客户端调用代理的方法时,代理会通过 Socket 连接到远程服务器,将请求发送给远程服务,然后返回结果。


import java.io.*;import java.net.*;
public class RemoteCalculationServiceProxy implements RemoteCalculationService { private String serverAddress; private int serverPort;
public RemoteCalculationServiceProxy(String serverAddress, int serverPort) { this.serverAddress = serverAddress; this.serverPort = serverPort; }
@Override public int add(int a, int b) { return sendRequest("add", a, b); }
@Override public int subtract(int a, int b) { return sendRequest("subtract", a, b); }
private int sendRequest(String operation, int a, int b) { try ( Socket socket = new Socket(serverAddress, serverPort); ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream()) ) { // 发送操作请求 outputStream.writeObject(operation); outputStream.writeInt(a); outputStream.writeInt(b); outputStream.flush();
// 读取结果 return inputStream.readInt(); } catch (IOException e) { e.printStackTrace(); } return 0; }}
复制代码


客户端


客户端通过 RemoteCalculationServiceProxy 访问远程计算服务。代理会将请求发送到服务器并接收响应。


public class Client {    public static void main(String[] args) {        RemoteCalculationService service = new RemoteCalculationServiceProxy("localhost", 8080);
// 通过代理调用远程服务 System.out.println("add 执行结果: " + service.add(10, 5)); System.out.println("subtract 执行结果: " + service.subtract(10, 5)); }}
复制代码


运行步骤


1.运行服务器端

首先运行服务器端RemoteServer,这会启动一个 ServerSocket 来监听客户端的请求。每当接收到客户端请求时,服务器会在一个新线程中处理。


2.运行客户端

然后启动客户端Client,它通过代理类与服务器端进行交互,发送计算请求并接收结果。


结果输出


远程服务端输出结果:


Server is running...

执行的操作:add

执行结果:15

执行的操作:subtract

执行结果:5


客户端输出结果


add 执行结果: 15

subtract 执行结果: 5


远程代理的应用


比如:Apache CXF 服务框架


import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
public class Client { public static void main(String[] args) { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(HelloWorldService.class); factory.setAddress("http://localhost:8080/hello"); HelloWorldService service = (HelloWorldService) factory.create(); System.out.println(service.sayHello("World")); }}
复制代码


配置服务接口 class 和服务路由,通过工厂模式创建对应的远程代理实例化对象,客户端只需要关注接口有什么方法即可,调用远程服务方法就像是调用本地方法一样。


比如:RPC协议框架,例如:dubbo、gRPC 等。


总结


通过这种实现,您可以模拟一个基于 Socket 的远程服务和远程代理的应用。客户端通过 RemoteCalculationServiceProxy 与远程服务进行通信,而远程服务通过RemoteCalculationServiceImpl 提供计算功能。客户端在使用代理对象进行操作时,就像是调用本地的方法一样,无感的实现远程方法的调用。这种调用方式又称为远程过程调用。常用的远程过程调用框架有 CXF、Dubbo、gRPC 等等,其核心思想之一都是远程代理,它实现了在本地调用远程服务时的透明性,使得远程调用看起来像本地调用。


文章转载自:渊渟岳

原文链接:https://www.cnblogs.com/dennyLee2025/p/18660712

体验地址:http://www.jnpfsoft.com/?from=001YH

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
用远程代理模式轻松实现远程服务调用,打开编程新大门_远程代理_不在线第一只蜗牛_InfoQ写作社区