我有一個客戶端,在服務器上啓動一個長時間運行的進程。定期,我想向用戶展示背景中發生的事情。最簡單的方法是輪詢服務器,但我想知道是否沒有辦法爲此實現Observer模式。不幸的是,我正在使用RMI與服務器交談,我擔心我必須將我的客戶端變成RMI服務器。如何使用Java RMI實現觀察者模式?
是否有另一種我失蹤的方式?
我有一個客戶端,在服務器上啓動一個長時間運行的進程。定期,我想向用戶展示背景中發生的事情。最簡單的方法是輪詢服務器,但我想知道是否沒有辦法爲此實現Observer模式。不幸的是,我正在使用RMI與服務器交談,我擔心我必須將我的客戶端變成RMI服務器。如何使用Java RMI實現觀察者模式?
是否有另一種我失蹤的方式?
我不認爲你錯過了任何東西。唯一的兩種方法是定期調用服務器並檢查狀態(輪詢)或註冊服務器定期調用的回調(您的客戶端必須公開方法)。國際海事組織,輪詢是一個完全合理的方式來處理這一點。
RMI一般可以支持雙向通信。 (是的,RMI是一個PITA來設置,並做任何事情。)
但是,通過CGI腳本(!)工作的HTTP傳輸不支持它。
當我使用LocateRegistry.createRegistry()在代碼中啓動服務器(而不是使用Sun提供的可執行文件)時,仍然如此嗎? – 2009-07-28 08:11:13
+1「(是的,RMI是PITA的設置,並與其他做任何事情。)」請告訴我的學校說。 – Luc 2014-06-13 23:00:56
這裏整合所有的答案,我實現了2路RMI客戶端和服務器之間,服務器暴露使用註冊表
下面的代碼將給出一個更好的主意
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.util.Observable;
import java.util.Observer;
import java.net.*;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
interface ReceiveMessageInterface extends Remote
{
/**
* @param x
* @throws RemoteException
*/
void receiveMessage(String x) throws RemoteException;
/**
* @param observer
* @throws RemoteException
*/
void addObserver(Remote observer) throws RemoteException;
}
/**
*
*/
class RmiClient extends UnicastRemoteObject
{
/**
* @param args
*/
static public void main(String args[])
{
ReceiveMessageInterface rmiServer;
Registry registry;
String serverAddress = args[0];
String serverPort = args[1];
String text = args[2];
System.out.println("sending " + text + " to " + serverAddress + ":" + serverPort);
try
{ // Get the server's stub
registry = LocateRegistry.getRegistry(serverAddress, (new Integer(serverPort)).intValue());
rmiServer = (ReceiveMessageInterface) (registry.lookup("rmiServer"));
// RMI client will give a stub of itself to the server
Remote aRemoteObj = (Remote) UnicastRemoteObject.exportObject(new RmiClient(), 0);
rmiServer.addObserver(aRemoteObj);
// call the remote method
rmiServer.receiveMessage(text);
// update method will be notified
}
catch (RemoteException e)
{
e.printStackTrace();
}
catch (NotBoundException e)
{
System.err.println(e);
}
}
public void update(String a) throws RemoteException
{
// update should take some serializable object as param NOT Observable
// and Object
// Server callsbacks here
}
}
/**
*
*/
class RmiServer extends Observable implements ReceiveMessageInterface
{
String address;
Registry registry;
/**
* {@inheritDoc}
*/
public void receiveMessage(String x) throws RemoteException
{
System.out.println(x);
setChanged();
notifyObservers(x + "invoked me");
}
/**
* {@inheritDoc}
*/
public void addObserver(final Remote observer) throws RemoteException
{
// This is where you plug in client's stub
super.addObserver(new Observer()
{
@Override
public void update(Observable o,
Object arg)
{
try
{
((RmiClient) observer).update((String) arg);
}
catch (RemoteException e)
{
}
}
});
}
/**
* @throws RemoteException
*/
public RmiServer() throws RemoteException
{
try
{
address = (InetAddress.getLocalHost()).toString();
}
catch (Exception e)
{
System.out.println("can't get inet address.");
}
int port = 3232;
System.out.println("this address=" + address + ",port=" + port);
try
{
registry = LocateRegistry.createRegistry(port);
registry.rebind("rmiServer", this);
}
catch (RemoteException e)
{
System.out.println("remote exception" + e);
}
}
/**
*
* @param args
*/
static public void main(String args[])
{
try
{
RmiServer server = new RmiServer();
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
}
我試圖做到這一點,以及和我來到了相同的結論...... RMI有點太差勁了! :) – JohnIdol 2009-12-15 19:06:56