Java MRI(Remote Method Invocation:远程方法调用)

RMI,是java提供的远程方法调用技术,能够通过普通方法调用的简单写法,就能实现分布式服务调用,下面是百度上的解释:

技术架构

RMI 框架采用代理来负责客户与远程对象之间通过 Socket 进行通信的细节。RMI 框架为远程对象分别生成了客户端代理和服务器端代理。位于客户端的代理必被称为存根(Stub),位于服务器端的代理类被称为骨架(Skeleton)

RMI的优缺点

优点:RMI代码简单,没有过多的配置,原理也很简单

缺点:基于JVM的规范,只能在JVM之间进行远程服务调用,不能跨语言调用

下面是一个1v1聊天的demo,完整源码:有角的圆/learn-java - Gitee.com

服务端代码

public class Server {
	
	public static void main(String[] args) {
        try {
            // 创建注册表(端口 1099) RMISocketFactory 
            Registry registry = LocateRegistry.createRegistry(1099);
            UserService service = new UserServiceImpl(registry);
            
            // 绑定服务到注册表
            registry.rebind("UserService", service);
            System.out.println("Server has started.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    
	}
}
UserService
public interface UserService extends Remote {
	
    // 客户端用户用户登录,通知服务端客户端上线了
    String login(String name) throws RemoteException;
    
    // 接收客户端用户发送的消息
	ResponseMessage say(RequestMessage message) throws RemoteException;
}
UserServiceImpl
/**
* 远程服务需要继承UnicastRemoteObject
*/
public class UserServiceImpl extends UnicastRemoteObject implements UserService {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Registry registry;
	
	public UserServiceImpl(Registry registry) throws RemoteException {
        super(); // 初始化远程对象
        this.registry=registry;
    }


	@Override
	public ResponseMessage say(RequestMessage message) throws RemoteException {
		try {
			System.out.println(message.getUser()+"->"+message.getTargetUser()+" : "+message.getMessage());
			IMessageListener eventListener = (IMessageListener)registry.lookup("listener-"+message.getTargetUser());
			eventListener.onEvent(message);
			return ResponseMessage.ok();
		} catch (Exception e) {
			e.printStackTrace();
			return ResponseMessage.err(e.getMessage());
		}
	}

	@Override
	public String login(String name) throws RemoteException {
		System.out.println("用户["+name+"]上线了");
		return null;
	}
}

客户端代码


public class Client {
	public static void main(String[] args) {
		try {
			// 获取注册表(需指定服务端 IP)
			Registry registry = LocateRegistry.getRegistry("localhost", 1099);

			// 查找远程对象
			UserService service = (UserService) registry.lookup("UserService");

			Scanner scanner = new Scanner(System.in);
			String line = "";
			RequestMessage helloMessage = new RequestMessage();
			helloMessage.setUser("");
			helloMessage.setTargetUser("");
			System.out.println("输入命令(login,target,message) l:张三  t:李四  m:hello 其他默认m:");
			while (true) {
				System.out.print(helloMessage.getUser() + "->" + helloMessage.getTargetUser() + ":");
				line = scanner.nextLine();
				if (line == null || "".equals(line.trim())) {
					continue;
				}
				if (line.startsWith("l:")) {
					helloMessage.setUser(line.substring(2));
					// 注册自身 用用户名绑定自身的消息监听器
					registry.rebind("listener-"+line.substring(2), new MessageListener(line.substring(2)));
					// 登录成功
					service.login(line.substring(2));
				} else if (line.startsWith("t:")) {
					helloMessage.setTargetUser(line.substring(2));
				} else if (line.startsWith("m:")) {
					helloMessage.setMessage(line.substring(2));
					ResponseMessage response = service.say(helloMessage);
					if (!response.isSuccess()) {
						System.out.println("Response: " + response.getErrMsg());
					}
				} else {
					helloMessage.setMessage(line);
					ResponseMessage response = service.say(helloMessage);
					if (!response.isSuccess()) {
						System.out.println("Response: " + response.getErrMsg());
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

启动服务度

启动两个客户端

命令简介

l:zhangsan //zhangsan登录

t:lisi // 选定目标lisi

m:msg // 发送消息,也可以省略m:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值