当前位置: 首页 > news >正文

RPC(6):RMI实现RPC

1RMI简介

RMI(Remote Method Invocation) 远程方法调用。

RMI是从JDK1.2推出的功能,它可以实现在一个Java应用中可以像调用本地方法一样调用另一个服务器中Java应用(JVM)中的内容。

RMI 是Java语言的远程调用,无法实现跨语言。

2 执行流程

Registry(注册表)是放置所有服务器对象的命名空间。 每次服务端创建一个对象时,它都会使用bind()或rebind()方法注册该对象。 这些是使用称为绑定名称的唯一名称注册的。

要调用远程对象,客户端需要该对象的引用。即通过服务端绑定的名称从注册表中获取对象(lookup()方法)。

3 API介绍

3.1 Remote

java.rmi.Remote 定义了此接口为远程调用接口。如果接口被外部调用,需要继承此接口。

3.2 RemoteException

java.rmi.RemoteException

继承了Remote接口的接口中,如果方法是允许被远程调用的,需要抛出此异常。

3.3 UnicastRemoteObject

java.rmi.server.UnicastRemoteObject

此类实现了Remote接口和Serializable接口。

自定义接口实现类除了实现自定义接口还需要继承此类。

3.4 LocateRegistry

java.rmi.registry.LocateRegistry

可以通过LocateRegistry在本机上创建Registry,通过特定的端口就可以访问这个Registry。

3.5 Naming

java.rmi.Naming

Naming定义了发布内容可访问RMI名称。也是通过Naming获取到指定的远程方法。

4 代码实现

4.1 创建RMI接口

编写接口文件

package com.example.demo;import java.rmi.Remote;
import java.rmi.RemoteException;// 定义一个远程服务接口。RMI强制要求,必须是Remote接口的实现。
public interface FirstInterface extends Remote {// RMI强制要求,所有的远程服务方法,必须抛出RemoteException。String first(String name) throws RemoteException;
}

4.2 创建服务端

引入pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>rmi_rpc</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>rmi_rpc_server</artifactId><dependencies><dependency><groupId>org.example</groupId><artifactId>rmi_rpc_api</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

编写远程服务接口

package com.example.demo.impl;import com.example.demo.FirstInterface;import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;// 实现远程服务接口。 所有的远程服务实现,必须是Remote接口直接或间接实现类。
// 如果不会创建基于RMI的服务标准实现,可以继承UnicastRemoteObject类型。
// RMI强制要求,所有的方法必须抛出RemoteException,包括构造方法。
public class FirstRMIImpl extends UnicastRemoteObject implements FirstInterface, Remote {public FirstRMIImpl() throws RemoteException {super();}public String first(String name) throws RemoteException {System.out.println("客户端请求参数是:" + name);return "你好," + name;}
}

创建启动类,将服务注册到Registry上

package com.example.demo;import com.example.demo.impl.FirstRMIImpl;import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;// 主方法,创建一个服务实现对象,提供服务,并注册到Registry上。
// RMI的Registry在创建的时候,会自动启动一个子线程,并升级为守护线程(服务线程|精灵线程)。提供持久的服务。
public class MainClass {public static void main(String[] args) {try {System.out.println("服务器启动中...");// 创建服务对象FirstInterface first = new FirstRMIImpl();// 注册到Registry(注册中心)上。LocateRegistry.createRegistry(9999);// 绑定一个服务到注册中心。提供命名,格式为:rmi://ip:port/别名// 如果服务重复,抛出异常。 重复的定义是命名冲突。// Naming.bind("rmi://localhost:9999/first", first);// 重新绑定一个服务到自注册中心。 和bind的区别是,命名冲突,直接覆盖。Naming.rebind("rmi://localhost:9999/first", first);System.out.println("服务器启动完毕!");}catch (Exception e){e.printStackTrace();}}
}

启动服务,结果如下:

4.3 创建客户端

引入pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>rmi_rpc</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>rmi_rpc_client</artifactId><dependencies><dependency><groupId>org.example</groupId><artifactId>rmi_rpc_api</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

编写服务调用RMI的RPC服务

package com.example.demo;import java.rmi.Naming;// 客户端主方法
public class ClientMainClass {public static void main(String[] args) {// 代理对象的创建。FirstInterface first = null;try{// 使用lookup找服务。通过名字找服务,并自动创建代理对象。// 类型是Object,对象一定是Proxy的子类型,且一定实现了服务接口。first = (FirstInterface) Naming.lookup("rmi://localhost:9999/first");System.out.println("对象的类型是:" + first.getClass().getName());String result = first.first("S106,今天课程讲不完了");System.out.println(result);}catch (Exception e){e.printStackTrace();}}
}

启动服务,结果如下:

这时候查看服务端程序,会显示连接申请的服务,效果如下:

相关文章:

RPC(6):RMI实现RPC

1RMI简介 RMI(Remote Method Invocation) 远程方法调用。 RMI是从JDK1.2推出的功能&#xff0c;它可以实现在一个Java应用中可以像调用本地方法一样调用另一个服务器中Java应用&#xff08;JVM&#xff09;中的内容。 RMI 是Java语言的远程调用&#xff0c;无法实现跨语言。…...

strlen和sizeof的初步理解

大家好我是Beilef&#xff0c;一个美好的下我接触到编程并且逐渐喜欢。我虽然不是科班出身但是我会更加努力地去学&#xff0c;有啥不对的地方请斧正 文章目录 目录 文章目录 前言 想必大家对sizeof肯定很了解&#xff0c;那对strlen又了解多少。其实这个问题应该让不少人困扰。…...

纯CSS的华为充电动画,它来了

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; Krpano专栏&#xff1a;想学Krpano的&#xff0c;冲 &#x1f514…...

在架构设计中,前后端分离有什么好处?

前后端分离是一种架构设计模式&#xff0c;将前端和后端的开发分别独立进行&#xff0c;它带来了多方面的好处&#xff1a; 1、独立开发和维护&#xff1a; 前后端分离允许前端和后端开发团队独立进行工作。这意味着两个团队可以并行开发&#xff0c;提高了整体的开发效率。前…...

C语言中的结构体和联合体:异同及应用

文章目录 C语言中的结构体和联合体&#xff1a;异同及应用1. 结构体&#xff08;Struct&#xff09;的概述代码示例&#xff1a; 2. 联合体&#xff08;Union&#xff09;的概述代码示例&#xff1a; 3. 结构体与联合体的异同点相同点&#xff1a;不同点&#xff1a;代码说明 结…...

文件夹共享(普通共享和高级共享的区别)防火墙设置(包括了jdk安装和Tomcat)

文章目录 一、共享文件1.1为什么需要配置文件夹共享功能&#xff1f;1.2配置文件共享功能1.3高级共享和普通共享的区别&#xff1a; 二、防火墙设置2.1先要在虚拟机上安装JDK和Tomcat供外部访问。2.2设置防火墙&#xff1a; 一、共享文件 1.1为什么需要配置文件夹共享功能&…...

❀My排序算法学习之冒泡排序❀

目录 冒泡排序(Bubble Sort):) 一、定义 二、算法原理 三、算法分析 时间复杂度 算法稳定性 算法描述 C语言 C++ 算法比较 插入排序 选择排序 快速排序 归并排序 冒泡排序(Bubble Sort):) 一、定义 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单…...

服务器数据恢复-raid6离线磁盘强制上线后分区打不开的数据恢复案例

服务器数据恢复环境&#xff1a; 服务器上有一组由12块硬盘组建的raid6磁盘阵列&#xff0c;raid6阵列上层有一个lun&#xff0c;映射到WINDOWS系统上使用&#xff0c;WINDOWS系统划分了一个GPT分区。 服务器故障&分析&#xff1a; 服务器在运行过程中突然无法访问。对服务…...

Zookeeper在分布式命名服务中的实践

Java学习面试指南&#xff1a;https://javaxiaobear.cn 命名服务是为系统中的资源提供标识能力。ZooKeeper的命名服务主要是利用ZooKeeper节点的树形分层结构和子节点的顺序维护能力&#xff0c;来为分布式系统中的资源命名。 哪些应用场景需要用到分布式命名服务呢&#xff1…...

说说 Spring Boot 实现接口幂等性有哪几种方案?

一、什么是幂等性 幂等是一个数学与计算机学概念&#xff0c;在数学中某一元运算为幂等时&#xff0c;其作用在任一元素两次后会和其作用一次的结果相同。 在计算机中编程中&#xff0c;一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数或幂等…...

Dash中的callback的使用 多input 6

代码说明 import plotly.express as pxmport plotly.express as px用于导入plotly.express模块并给它起一个别名px。这样在后续的代码中&#xff0c;你可以使用px来代替plotly.express&#xff0c;使代码更加简洁。 plotly.express是Plotly的一个子模块&#xff0c;用于快速创…...

平方矩阵()

平方矩阵1 平方矩阵2 曼哈顿距离 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring>using namespace std;const int N 110;int n; int a[N][N];int main() {while(cin >> n, n){for (int i 0; i < n; i )fo…...

git基本命令

1、安装 介绍 安装 配置 2、git基本命令 2.1 基本操作 #1、查看空目录的git状态 $ git status fatal: not a git repository (or any of the parent directories): .git#2、初始化本地仓库&#xff1a;创建一个git的目录管理当前项目的所有文件版本 $ git init Initializ…...

GPU性能实时监测的实用工具

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

概率论中的 50 个具有挑战性的问题 [第 6 部分]:Chuck-a-Luck

一、说明 我最近对与概率有关的问题产生了兴趣。我偶然读到了弗雷德里克莫斯特勒&#xff08;Frederick Mosteller&#xff09;的《概率论中的五十个具有挑战性的问题与解决方案》&#xff09;一书。我认为创建一个系列来讨论这些可能作为面试问题出现的迷人问题会很有趣。每篇…...

windows搭建MySQL主从补充说明

这3种情况是在HA切换时&#xff0c;由于是异步复制&#xff0c;且sync_binlog0&#xff0c;会造成一小部分binlog没接收完导致同步报错。 第一种&#xff1a;在master上删除一条记录&#xff0c;而slave上找不到。 第二种&#xff1a;主键重复。在slave已经有该记录&#xff…...

Python:GUI Tkinter

GUI编程 GUI编程&#xff08;Graphical User Interface Programming&#xff09;指的是用于创建图形用户界面的程序设计。这种界面采用图形方式显示信息&#xff0c;让用户可以通过图形化的方式与程序进行交互&#xff0c;而不是仅仅通过文本命令。GUI编程使得软件更加直观易用…...

制作一个可以离线安装的Visual Studio安装包

须知 前提条件&#xff0c;需要电脑可以正常上网且网速还行&#xff0c;硬盘可以空间容量足够大&#xff0c;怎么判断容量够用&#xff1f;由组件数量的多少来决定。Visual Studio 频道和发布节奏 https://learn.microsoft.com/zh-cn/visualstudio/productinfo/release-rhythm…...

机器学习——决策树(三)

【说明】文章内容来自《机器学习——基于sklearn》&#xff0c;用于学习记录。若有争议联系删除。 1、案例一 决策树用于是否赖床问题。 采用决策树进行分类&#xff0c;要经过数据采集、特征向量化、模型训练和决策树可视化4个步骤。 赖床数据链接&#xff1a;https://pan…...

模型量化之AWQ和GPTQ

什么是模型量化 模型量化&#xff08;Model Quantization&#xff09;是一种通过减少模型参数表示的位数来降低模型计算和存储开销的技术。一般来说&#xff0c;模型参数在深度学习模型中以浮点数&#xff08;例如32位浮点数&#xff09;的形式存储&#xff0c;而模型量化可以…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...