Não é nenhum bicho de sete cabeças fazer o que você quer.
É só você implementar uma estrutura de listeners, só que com a interface Remote
.
Interface do serviço que recebe o X e o Y e permite que seja registrado um listener:
package exemplo.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Servico extends Remote {
void addListener(ServicoListener listener) throws RemoteException;
void setX(double valor) throws RemoteException;
void setY(double valor) throws RemoteException;
}
Interface do listener para o serviço acima:
package exemplo.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ServicoListener extends Remote {
void calculoEfetuado(double resultado) throws RemoteException;
}
Implementação da interface do serviço:
package exemplo.rmi.server;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import exemplo.rmi.Servico;
import exemplo.rmi.ServicoListener;
class ImplementacaoServico implements Servico {
private final List<ServicoListener> listeners = new ArrayList<>();
private boolean setouX;
private boolean setouY;
private double valorX;
private double valorY;
@Override
public void addListener(ServicoListener listener) throws RemoteException {
listeners.add(listener);
}
@Override
public void setX(double valor) throws RemoteException {
valorX = valor;
setouX = true;
verifica();
}
@Override
public void setY(double valor) throws RemoteException {
valorY = valor;
setouY = true;
verifica();
}
private void verifica() {
if (setouX && setouY) {
double resultado = valorX + valorY;
for (ServicoListener listener : listeners) {
try {
listener.calculoEfetuado(resultado);
} catch (RemoteException e) {
e.printStackTrace();
}
}
setouX = false;
setouY = false;
}
}
}
Implementação do servidor que disponibiliza o serviço acima:
package exemplo.rmi.server;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import exemplo.rmi.Servico;
public class Servidor {
public static void main(String args[]) {
try {
String nomeServico = "MeuServico";
int porta = 12345;
Servico servico = new ImplementacaoServico();
Servico servicoDistribuido = (Servico) UnicastRemoteObject.exportObject(servico, 0);
Registry registry = LocateRegistry.createRegistry(porta);
registry.bind(nomeServico, servicoDistribuido);
System.out.printf("Servico disponivel: %s%n", nomeServico);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Implementação do cliente A que faz o setX:
package exemplo.rmi.client;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import exemplo.rmi.Servico;
import exemplo.rmi.ServicoListener;
public class ClienteA implements ServicoListener {
public static void main(String[] args) {
try {
String nomeServico = "MeuServico";
int porta = 12345;
ServicoListener clienteA = new ClienteA();
ServicoListener clienteAdistribuido = (ServicoListener) UnicastRemoteObject.exportObject(clienteA, 0);
Registry registry = LocateRegistry.getRegistry(porta);
Servico servicoRemoto = (Servico) registry.lookup(nomeServico);
servicoRemoto.addListener(clienteAdistribuido);
double valor = 20;
System.out.println("Cliente A enviando: " + valor);
servicoRemoto.setX(valor);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void calculoEfetuado(double resultado) throws RemoteException {
System.out.println("Servidor devolveu para Cliente A o resultado: " + resultado);
}
}
Implementação do cliente B, que faz o setY perceba que o código é análogo ao do cliente A, você pode criar uma abstração para isso:
package exemplo.rmi.client;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import exemplo.rmi.Servico;
import exemplo.rmi.ServicoListener;
public class ClienteB implements ServicoListener {
public static void main(String[] args) {
try {
String nomeServico = "MeuServico";
int porta = 12345;
ServicoListener clienteB = new ClienteB();
ServicoListener clienteBdistribuido = (ServicoListener) UnicastRemoteObject.exportObject(clienteB, 0);
Registry registry = LocateRegistry.getRegistry(porta);
Servico servicoRemoto = (Servico) registry.lookup(nomeServico);
servicoRemoto.addListener(clienteBdistribuido);
double valor = 10;
System.out.println("Cliente B enviando: " + valor);
servicoRemoto.setY(valor);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void calculoEfetuado(double resultado) throws RemoteException {
System.out.println("Servidor devolveu para Cliente B o resultado: " + resultado);
}
}