原始问题:
我遇到了一个问题,该问题不允许我的客户端-服务器程序在本地范围之外运行。 该程序必须处理服务器(称为“代理”)和客户端的网络,它们可以在其中创建或遵循某些“主题”。为了做到这一点,客户必须连接到托管其主题列表和其子网订阅的代理(经纪人也必须能够担当客户角色,但我仍然必须从事此工作)。
我正在与一个扮演代理角色的朋友在Eclipse中进行测试,但是每次我尝试与他联系时,我都会遇到相同的错误,那就是您看到的错误。 我已经尝试了各种方式,在我告诉你的情况下,我已经输入了朋友的dns地址,该程序似乎找到了它,因为在错误中它指示了他的pc的本地地址,所以我不了解我们为什么会收到此错误。
错误
当我尝试连接到正在收听的朋友时,会发生以下情况:
java.rmi.ConnectException: Connection refused to host: 192.168.1.57; nested exception is:
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
at com.sun.proxy.$Proxy0.connectClient(Unknown Source)
at forumPCAD.PCADClient.connectTo(PCADClient.java:47)
at forumPCAD.PCADClient.MenuConsole(PCADClient.java:133)
at forumPCAD.PCADClient.main(PCADClient.java:217)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 9 more
最后更新
这是该代码的最新版本,问题尚未解决。
服务器端:
package forumPCAD;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NoSuchObjectException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import addressHandlers.RmiAddressHandler;
import addressHandlers.ipChecker;
public class PCADBroker extends UnicastRemoteObject implements Broker, Client {
private static final long serialVersionUID = 1L;
protected Client brokerStub; //Lo stub da esportare corrispondente a questo broker
protected Broker superBroker; //Il riferimento al broker a cui questo si connette
List<Topic> superBrokerTopics; //I topic del superbroker a cui questo è iscritto
List<Topic> brokerTopics; //I topic gestiti da questo broker
List<Client> stubsClients; //Gli stub dei client connessi a questo broker
ConcurrentHashMap<Topic, List<String>> brokerSubscriptions; //Le associazioni tra i topic e i nomi dei client iscritti ad essi
protected String brokerName; //Il nome del broker
protected String brokerPublicIP; //L'indirizzo IP del broker
protected String brokerURL; //L'url completo del broker
public PCADBroker(String brokerName) throws RemoteException {
super();
brokerStub = null;
superBroker = null;
superBrokerTopics = new CopyOnWriteArrayList<Topic>();
brokerTopics = new CopyOnWriteArrayList<Topic>();
stubsClients = new CopyOnWriteArrayList<Client>();
brokerSubscriptions = new ConcurrentHashMap<Topic, List<String>>();
this.brokerName = brokerName;
this.brokerPublicIP = ipChecker.checkPublicIp();
this.brokerURL = "rmi://" + brokerPublicIP + "/" + brokerName;
}
@Override
public void startListening() throws RemoteException, MalformedURLException {
System.setProperty("java.security.policy","file:./sec.policy");
if(System.getSecurityManager() == null) System.setSecurityManager(new SecurityManager());
try {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
} catch(RemoteException e){
LocateRegistry.getRegistry(Registry.REGISTRY_PORT);
}
System.out.println("Istanza PCADBroker creata");
Naming.rebind(brokerName, this);
System.out.println("Il Broker \"" + brokerName + "\" è in ascolto all'URL: " + brokerURL);
}
public void stopListening() throws RemoteException, MalformedURLException, NotBoundException {
if(System.getSecurityManager() == null) System.setSecurityManager(new SecurityManager());
try {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
} catch(RemoteException e){
LocateRegistry.getRegistry(Registry.REGISTRY_PORT);
}
Naming.unbind(brokerName);
System.out.println("Broker ha smesso di ascoltare all'URL: " + brokerURL);
}
@Override
public synchronized boolean connectClient(Client stubClient) throws RemoteException{
if(stubsClients.isEmpty())
return stubsClients.add(stubClient);
for(Client client : stubsClients) {
if(client.getName().equals(stubClient.getName()))
return false;
}
return stubsClients.add(stubClient);
}
//Utilizza il foreach perchè in questo caso il metodo è di sola lettura e confronto.
@Override
public synchronized boolean disconnectClient(Client stubClient) throws RemoteException{
if(stubsClients.isEmpty())
return false;
for(Client client : stubsClients) {
if(client.getName().equals(stubClient.getName())) {
stubsClients.remove(stubsClients.indexOf(client));
return true;
}
}
return false;
}
//Verificare che sia il metodo migliore per rimuovere da una lista CopyOnWrite.
@Override
public List<Topic> getBrokerTopics() throws RemoteException{
List<Topic> brokerTopicsList = new CopyOnWriteArrayList<Topic>(brokerTopics);
if(!superBrokerTopics.isEmpty()) {
List<Topic> superBrokerTopicsList = new CopyOnWriteArrayList<Topic>(superBrokerTopics);
brokerTopicsList.addAll(superBrokerTopicsList);
}
return brokerTopicsList;
}
//La lista ritornata dovrà contenere i topic del broker + i topic del superbroker a cui il broker è iscritto.
@Override
public synchronized boolean subscribeClient(Client subscriber, String topicTitle) throws RemoteException{
String subscriberName = subscriber.getName();
Topic theTopic = null;
//Ricerca del topic tra quelli originari del broker
if(!brokerTopics.isEmpty()) {
for(Topic topic : brokerTopics)
theTopic = (topic.getTitle().equals(topicTitle) ? topic : null);
}
if(theTopic != null) {
if(!brokerSubscriptions.get(theTopic).contains(subscriberName))
return brokerSubscriptions.get(theTopic).add(subscriberName);
return false;
}
//Ricerca del topic tra quelli originari del superBroker
if(!superBrokerTopics.isEmpty()) {
for(Topic topic : superBrokerTopics)
theTopic = (topic.getTitle().equals(topicTitle) ? topic : null);
}
if(theTopic != null) {
if(!brokerSubscriptions.get(theTopic).contains(subscriberName))
return brokerSubscriptions.get(theTopic).add(subscriberName);
return false;
}
return false;
}
//Il client può vedere nella lista i topic del superbroker a cui il broker è iscritto e iscrivervisi a sua volta.
//L'iscrizione è sempre memorizzata in brokerSubscriptions.
@Override
public synchronized boolean unsubscribeClient(Client subscriber, String topicTitle) throws RemoteException{
String subscriberName = subscriber.getName();
Topic theTopic = null;
//Ricerca del topic tra quelli originari del broker
for(Topic topic : brokerTopics) {
theTopic = topic.getTitle().equals(topicTitle) ? topic : null;
}
if(theTopic != null) {
if(brokerSubscriptions.get(theTopic).contains(subscriberName))
return brokerSubscriptions.get(theTopic).remove(subscriberName);
return false;
}
//Ricerca del topic tra quelli originari del superBroker
if(!superBrokerTopics.isEmpty()) {
for(Topic topic : superBrokerTopics)
theTopic = topic.getTitle().equals(topicTitle) ? topic : null;
}
if(theTopic != null) {
if(brokerSubscriptions.get(theTopic).contains(subscriberName))
return brokerSubscriptions.get(theTopic).remove(subscriberName);
return false;
}
return false;
}
//Il client può vedere nella lista i topic del superbroker a cui si era iscritto e disiscrivervisi.
//L'iscrizione viene tolta da brokerSubscriptions.
@Override
public synchronized boolean publishTopic(Topic topic) throws RemoteException{
for(Topic aTopic : brokerTopics) {
if(topic.getTitle().equals(aTopic.getTitle()))
return false;
}
if(brokerTopics.add(topic)){
brokerSubscriptions.put(topic, new CopyOnWriteArrayList<String>());
return true;
}
return false;
}
//Controlla che non ci sia già un topic con titolo uguale, poi aggiunge il nuovo topic nella lista del broker.
@Override
public synchronized boolean publishAndBroadcastNotification(String publisherName, String topicTitle, String notification) throws RemoteException{
Topic theTopic = null;
for(Topic aTopic : brokerTopics)
theTopic = aTopic.getTitle().equals(topicTitle) ? aTopic : null;
if(theTopic == null)
for(Topic aTopic : superBrokerTopics)
theTopic = aTopic.getTitle().equals(topicTitle) ? aTopic : null;
if(theTopic == null){
Topic newTopic = new PCADTopic(publisherName, topicTitle, topicTitle + " (Topic generato automaticamente)");
return publishTopic(newTopic);
}
if(theTopic.getPublisherUsername().equals(publisherName)) {
if(brokerSubscriptions.get(theTopic).isEmpty())
return true;
brokerSubscriptions.get(theTopic).forEach(subscriber->{
try {
for(Client client : stubsClients){
if(client.getName().equals(subscriber))
client.receiveNotification(publisherName, topicTitle, notification);
}
} catch (RemoteException e) {
e.printStackTrace();
}
});
return true;
}
return false;
}
//Decidere se comunicare la creazione automatica del topic, magari usando il topic di servizio dell'idea.
@Override
public boolean connectTo(String IpAddress, String brokerName) throws MalformedURLException, RemoteException {
//return connectTo("rmi://" + IpAddress + "/" + brokerName);
try {
System.setProperty("java.security.policy","file:./sec.policy");
if (System.getSecurityManager() == null)
System.setSecurityManager(new SecurityManager());
LocateRegistry.getRegistry(IpAddress, Registry.REGISTRY_PORT);
superBroker = (Broker) Naming.lookup(brokerName);
try {
brokerStub = (Client) UnicastRemoteObject.exportObject(this,0);
}
catch(RemoteException e) {
brokerStub = (Client) UnicastRemoteObject.toStub(this);
}
return superBroker.connectClient(brokerStub);
}
catch (RemoteException | NotBoundException e) {
e.printStackTrace();
return false;
}
}
//Questo broker si connette al superBroker indicato e inizializza la lista in cui memorizzare i topic a cui si iscriverà.
@Override
public boolean disconnectFromBroker() throws RemoteException, NoSuchObjectException {
return superBroker == null ? false : superBroker.disconnectClient(brokerStub);
}
public List<Topic> getTopics() throws RemoteException{
return superBroker == null ? null : superBroker.getBrokerTopics();
}
@Override
public boolean subscribeTo(String topicTitle) throws RemoteException {
if(superBroker == null)
return false;
if(superBroker.subscribeClient(brokerStub, topicTitle)) {
for(Topic topic : superBroker.getBrokerTopics()) {
if(topic.getTitle().equals(topicTitle)) {
if(superBrokerTopics.add(topic)) {
brokerSubscriptions.put(topic, new CopyOnWriteArrayList<String>());
return true;
}
}
}
}
return false;
}
//Questo broker si iscrive al topic del superBroker, poi recupera il topic stesso dalla lista del superBroker e lo aggiunge a superBrokerTopics.
//Non controlla se ci sono topic con lo stesso titolo.
@Override
public boolean unsubscribeFrom(String topicTitle) throws RemoteException {
if(superBroker == null)
return false;
if(superBroker.unsubscribeClient(brokerStub, topicTitle)) {
for(Topic topic : superBroker.getBrokerTopics()) {
if(topic.getTitle().equals(topicTitle)) {
//publishAndBroadcastNotification(publisherName, topicTitle, "This topic has been removed");
if(superBrokerTopics.remove(topic)) {
brokerSubscriptions.remove(topic);
return true;
}
}
}
}
return false;
}
//Questo broker si disiscrive dal topic del superBroker, poi recupera il topic stesso dalla lista del superBroker e lo rimuove da superBrokerTopics.
//Idea: aggiunger un topic di servizio dove il broker può inviare comunicazioni come questa
@Override
public boolean receiveNotification(String publisher, String topicTitle, String notification) throws RemoteException {
return publishAndBroadcastNotification(publisher, topicTitle, notification);
}
//Gira la notifica, mettendosi come autore della stessa,
@Override
public boolean publishTopicOnBroker(Topic topic) throws RemoteException {
System.out.println("Un broker non può pubblicare topic su altri broker"); //renderli inutilizzabili in qualche modo
return false;
}
//Idea: aggiunger un topic di servizio dove il broker può inviare comunicazioni.
@Override
public String getName() throws RemoteException{
return brokerName;
}
@Override
public boolean verifySubscription(Topic topic) throws RemoteException{
return superBroker.verifySubscription(this, topic);
}
@Override
public boolean verifySubscription(Client subscriber, Topic topic) throws RemoteException{
return brokerSubscriptions.isEmpty() ? false : brokerSubscriptions.get(topic) == null || brokerSubscriptions.get(topic).isEmpty() ? false : brokerSubscriptions.get(topic).contains(subscriber.getName());
}
@Override
public boolean sendNotification(String topicTitle, String notification) throws RemoteException {
System.out.println("Un broker non può inviare notifiche"); //renderli inutilizzabili in qualche modo
return false;
}
//Idea: aggiunger un topic di servizio dove il broker può inviare comunicazioni.
private void MenuConsole() throws RemoteException, MalformedURLException, NotBoundException { //Aggiungere opzione visualizza iscrizioni
try{
Scanner keyboard = new Scanner(System.in);
boolean exit = false;
boolean listening = false;
boolean connectedToBroker = false;
RmiAddressHandler rmiAddressHandler = new RmiAddressHandler();
System.out.println(getName());
while(!exit) {
System.out.println("Cosa si desidera fare?");
System.out.println("1) " + (listening ? "Smettere di ascoltare" : "Mettersi in ascolto"));
if(listening) System.out.println("2) Vedere la lista dei Client collegati");
System.out.println("3) Leggere la lista dei Topic di questo Broker");
System.out.println("4) " + (connectedToBroker ? "Disconnettersi dal superBroker" : "Connettersi ad un altro Broker"));
if(connectedToBroker) {
System.out.println("5) Leggere la lista dei Topic del superBroker");
System.out.println("6) Iscriversi ad un topic (rendendolo visibile ai propri Client)");
System.out.println("7) Disiscriversi da un topic (eliminando le iscrizioni dei propri Client)");
}
System.out.println("0) Uscire " + (listening || connectedToBroker ? "(Chiudendo le connessioni attive)" : ""));
switch(Integer.parseInt(keyboard.nextLine())) {
case 1:
if(listening) stopListening();
else startListening();
listening = !listening;
break;
case 2:
if(!listening) {
System.out.println("Scelta non valida, riprovare");
break;
}
if(stubsClients.isEmpty())
break;
for(Client client : stubsClients)
System.out.println("Username: " + client.getName());
break;
case 3:
if(brokerTopics.isEmpty()) {
System.out.println("Nessun Topic presente");
break;
}
for(Topic topic : brokerTopics)
System.out.println("Titolo: " + topic.getTitle());
break;
case 4:
if(connectedToBroker) {
disconnectFromBroker();
connectedToBroker = false;
}
else {
System.out.println("Inserire l'indirizzo del broker: ");
String url = keyboard.nextLine();
String address = rmiAddressHandler.getAddressFromRmiAddress(url);
String brokerName = rmiAddressHandler.getNameFromRmiAddress(url);
connectedToBroker = connectTo(address, brokerName);
}
break;
case 5:
if(!connectedToBroker) {
System.out.println("Scelta non valida, riprovare");
break;
}
List<Topic> topicList = getTopics();
if(topicList.isEmpty()) {
System.out.println("Nessun Topic presente");
break;
}
for(Topic topic : topicList) {
System.out.println("Titolo: " + topic.getTitle() + (verifySubscription(topic) ? "\tIscritto" : ""));
}
break;
case 6:
if(!connectedToBroker) {
System.out.println("Scelta non valida, riprovare");
break;
}
System.out.println("Inserire il titolo del Topic: ");
subscribeTo(keyboard.nextLine());
break;
case 7:
if(!connectedToBroker) {
System.out.println("Scelta non valida, riprovare");
break;
}
System.out.println("Inserire il titolo del Topic: ");
unsubscribeFrom(keyboard.nextLine());
break;
case 0:
exit = true;
if(listening) stopListening();
break;
default:
System.out.println("Scelta non valida, riprovare");
}
}
keyboard.close();
System.exit(0);
}
catch(Exception e) {
stopListening();
disconnectFromBroker();
}
}
public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException {
Scanner keyboard = new Scanner(System.in);
System.out.println("Inserire il nome del Broker da istanziare:");
PCADBroker broker = new PCADBroker(keyboard.nextLine());
broker.MenuConsole();
keyboard.close();
}
}
客户端:
package forumPCAD;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NoSuchObjectException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList;
import addressHandlers.RmiAddressHandler;
public class PCADClient implements Client {
private static final long serialVersionUID = 1L;
private String username;
private Client stub;
private Broker broker;
List<String> notifications;
public PCADClient(String username) throws RemoteException {
this.username = username;
stub = null;
broker = null;
notifications = new CopyOnWriteArrayList<String>();
}
public boolean connectTo(String IpAddress, String brokerName) throws MalformedURLException, RemoteException {
try {
System.setProperty("java.security.policy","file:./sec.policy");
if (System.getSecurityManager() == null)
System.setSecurityManager(new SecurityManager());
LocateRegistry.getRegistry(IpAddress, Registry.REGISTRY_PORT);
broker = (Broker) Naming.lookup("rmi://" +IpAddress + "/" + brokerName);
try {
stub = (Client) UnicastRemoteObject.exportObject(this,0);
}
catch(RemoteException e) {
stub = (Client) UnicastRemoteObject.toStub(this);
}
return broker.connectClient(stub);
}
catch (RemoteException | NotBoundException e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean disconnectFromBroker() throws RemoteException, NoSuchObjectException {
if(!broker.disconnectClient(stub))
return false;
LocateRegistry.getRegistry(Registry.REGISTRY_PORT);
return UnicastRemoteObject.unexportObject(this,false);
}
public List<Topic> getTopics() throws RemoteException{
return broker.getBrokerTopics();
}
@Override
public boolean subscribeTo(String topicTitle) throws RemoteException {
return broker.subscribeClient(stub, topicTitle);
}
@Override
public boolean unsubscribeFrom(String topicTitle) throws RemoteException {
return broker.unsubscribeClient(stub, topicTitle);
}
@Override
public boolean publishTopicOnBroker(Topic topic) throws RemoteException {
return broker.publishTopic(topic);
}
@Override
public boolean receiveNotification(String publisher, String topicTitle, String notification) throws RemoteException{
return notifications.add("---\nNotifica da: " + publisher + "\nSul topic: "+ topicTitle + "\nTesto: " + notification + "\n---");
}
@Override
public boolean sendNotification(String topicTitle, String notification) throws RemoteException {
return broker.publishAndBroadcastNotification(username, topicTitle, notification);
}
public String getName() {
return username;
}
public void setName(String username) {
this.username = username;
}
public boolean verifySubscription(Topic topic) throws RemoteException {
return broker.verifySubscription(this, topic);
}
private void MenuConsole() throws RemoteException, MalformedURLException, NotBoundException {
try {
Scanner keyboard = new Scanner(System.in);
boolean exit = false;
boolean connectedToBroker = false;
RmiAddressHandler rmiAddressHandler = new RmiAddressHandler();
while(!exit) {
System.out.println("Cosa si desidera fare?");
System.out.println("1) " + (connectedToBroker ? "Disconnettersi dal Broker" : "Connettersi ad un Broker"));
if(connectedToBroker) {
System.out.println("2) Leggere la lista dei topic");
System.out.println("3) Pubblicare un nuovo topic");
System.out.println("4) Iscriversi ad un topic");
System.out.println("5) Disiscriversi da un topic");
System.out.println("6) Inviare una notifica su un topic (creandolo se non esiste)");
}
System.out.println("7) Controllare le notifiche");
System.out.println("0) Esci " + (connectedToBroker ? "(Chiudendo le connessioni attive)" : ""));
switch(Integer.parseInt(keyboard.nextLine())) {
case 1:
if(connectedToBroker) {
disconnectFromBroker();
connectedToBroker = false;
}
else {
System.out.println("Inserire l'indirizzo del broker: ");
String url = keyboard.nextLine();
String address = rmiAddressHandler.getAddressFromRmiAddress(url);
String brokerName = rmiAddressHandler.getNameFromRmiAddress(url);
connectedToBroker = connectTo(address, brokerName);
}
break;
case 2:
if(!connectedToBroker) {
System.out.println("Scelta non valida, riprovare");
break;
}
List<Topic> topicList = getTopics();
if(topicList.isEmpty()) {
System.out.println("Nessun Topic presente");
break;
}
for(Topic topic : topicList) {
System.out.println("Titolo: " + topic.getTitle() + (verifySubscription(topic) ? "\tIscritto" : ""));
}
break;
case 3:
if(!connectedToBroker) {
System.out.println("Scelta non valida, riprovare");
break;
}
System.out.println("Inserire un titolo per il nuovo Topic: ");
String title = keyboard.nextLine();
System.out.println("Inserire una descrizione per il nuovo Topic: ");
String description = keyboard.nextLine();
publishTopicOnBroker(new PCADTopic(username, title, description));
break;
case 4:
if(!connectedToBroker) {
System.out.println("Scelta non valida, riprovare");
break;
}
System.out.println("Inserire il titolo del Topic: ");
subscribeTo(keyboard.nextLine());
break;
case 5:
if(!connectedToBroker) {
System.out.println("Scelta non valida, riprovare");
break;
}
System.out.println("Inserire il titolo del Topic: ");
unsubscribeFrom(keyboard.nextLine());
break;
case 6:
if(!connectedToBroker) {
System.out.println("Scelta non valida, riprovare");
break;
}
System.out.println("Inserire il titolo del Topic: ");
String topicTitle = keyboard.nextLine();
System.out.println("Scrivere il testo della notifica: ");
String notification = keyboard.nextLine();
sendNotification(topicTitle, notification);
break;
case 7:
if(notifications.isEmpty()) {
System.out.println("Non ci sono notifiche");
break;
}
for(String aNotification : notifications)
System.out.println(aNotification);
break;
case 0:
if(connectedToBroker)
disconnectFromBroker();
exit = true;
break;
default:
System.out.println("Scelta non valida, riprovare");
}
}
keyboard.close();
System.exit(0);
}
catch (Exception e){
disconnectFromBroker();
}
}
public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException {
Scanner keyboard = new Scanner(System.in);
System.out.println("Inserire il nome del Client da istanziare:");
PCADClient client = new PCADClient(keyboard.nextLine());
client.MenuConsole();
keyboard.close();
}
}
答案 0 :(得分:0)
System.setProperty("java.rmi.server.hostname","localhost");
这是问题所在。您需要进行设置,但是要设置为服务器主机的公共IP地址,可以从外部访问该地址。
"localhost"
是您要设置为 last 的对象。
编辑:
super();
如果您有防火墙,这将永远无法工作。更改为使用固定端口。最简单的解决方案是使用LocateRegistry.createRegistry(Registry.REGISTRY_PORT)
在进程内部创建RMI注册表,然后使用super(REGISTRY_PORT)
将您的远程对象导出到相同的端口,这实际上应默认发生。并确保防火墙转发端口1099。