2016-06-23 26 views
0

Ich schreibe eine Anwendung, die RMI Connection Factories verwendet, so dass ich vor dem Aufruf einer Remote-Methode ein Timeout auf der Client-Seite festlegen kann. Ich möchte dies tun, damit der Client auf einen Anruf zu einem entfernten Verfahren für eine vorbestimmte Zeit warten kann, bevor er den Anruf aufgibt und aufgibt.Es scheint, dass ich die Socket-Factory nicht von einem RMI-Stub bekommen kann. Wieso ist es so?

Ich habe eine Socket Factory erstellt, die diesen Mechanismus erleichtert. Ich erstelle den Remote-Stub mit UnicastRemoteObject.exportObject(Remote, int, RMIServerSocketFactory, RMIClientSocetFactory), damit der Client den Stub mit der angepassten Socket-Factory verwenden kann, deren Klassendefinition beiden Geräten bekannt ist.

Die Socket Factory des Clients muss die Zeitüberschreitung festlegen, bevor der Server aufgerufen wird. Der Kunde entscheidet über die Länge dieses Timeouts. Ich kann eine Steckdosenfabrik herstellen, die auf diese Weise funktioniert. Es scheint jedoch, dass ich auf dem Client nicht sicherstellen kann, dass der Remote-Stub diese angepasste Socket-Factory hat, und daher kann ich nicht sicherstellen, dass die Client-Socket-Factory einen Client-Socket mit einer Zeitüberschreitung erstellt.

Ich frage mich, ob es eine Methode gibt, die auf eine Art funktionieren würde, wie ich es mir vorstellen würde Remote.getClientFactory() sollte funktionieren? Dies scheint mir ein offensichtliches Merkmal zu sein, das von der RMI-Spezifikation nicht abgedeckt wird. Gibt es in Ermangelung dieser Methode vielleicht einen gut benutzten "Hack", um die Socket-Factory des Clients auf dem Client abzurufen, so dass eine Zeitüberschreitung festgelegt werden kann?

Antwort

0
  1. Es würde Sie viel Gutes, auch wenn Sie konnte es nicht tun, wie Sie brauchen, was nicht die Fabrik ist aber die eigentliche Buchse, die verwendet werden soll, um den Anruf zu tätigen, und das ist aufgrund Client nicht vorhersagbar -Seite Verbindungspooling.

  2. Sie könnten vor jedem Anruf versuchen, sun.rmi.transport.tcp.responseTimeout anzupassen, aber ich habe ein unangenehmes Gefühl, es wird nur einmal in der Lebensdauer der JVM gelesen.

  3. Andernfalls können Sie für jedes Remote-Objekt eine andere Socket-Factory und für jede Remote-Schnittstelle ein anderes Remote-Objekt und für jede Remote-Methode eine andere Remote-Schnittstelle verwenden, sodass jeder Socket-Factory eine eindeutige Remote-Methode zugeordnet wird. .. und weisen Sie dann bei Bedarf jeder Factory einen Socket-Lese-Timeout zu, aber es ist immer noch serverseitig; und es spielt Chaos mit Connection-Pooling.

  4. Oder wenn Sie die inoffizielle unter der Motorhaube wollen may-nicht-Arbeit-next-Release nicht konform don't use sun.* classes freche Version:

    RemoteRef remoteRef; 
    if (stub instanceof RemoteStub) 
    { 
        remoteRef = ((RemoteStub)stub).getRef(); 
    } 
    else 
    { 
        // dynamic proxy 
        RemoteObjectInvocationHandler roih = (RemoteObjectInvocationHandler)java.lang.reflect.Proxy.getInvocationHandler(stub); 
        remoteRef = roih.getRef(); 
    } 
    if (remoteRef instanceof sun.rmi.server.UnicastRef2) 
    { 
        // JRMP stub with client socket factory. 
        // NB UnicastRef.getLiveRef() was added somewhere between 1.3 and 1.6. 
        // Previously it was only obtainable via reflection. 
        RMIClientSocketFactory csf = ((sun.rmi.server.UnicastRef2)remoteRef).getLiveRef().getClientSocketFactory(); 
        // YOUR CODE GOES HERE 
        // Note that 'csf' can still be null here, if you exported the remote object with an *explicitly null* client socket factory parameter. 
    } 
    

    jedoch den Vorbehalt stelle ich mit bei (1) gestartet . Das mag dir nicht viel nützen.

+0

Danke nochmal EJP. Ich habe eine Vorliebe für Option 4. Es sieht so aus, als würde ich etwas herstellen, das diese Option verwendet, und dann auf eine aktualisierte RMI-Spezifikation warten, um mir zu sagen, dass ich unartig bin. –

+0

Es ist schon unanständig, 'sun.rmi. *' Klassen zu verwenden. Ich würde nicht den Atem anhalten und auf irgendwelche Änderungen in RMI warten. Seit dem 1.5 im Jahr 2004 ist nichts mehr passiert. – EJP

+0

Hmmm ... 'RemoteStub' ist veraltet ... Ich nehme an, das Zeug im wahren Fall ist rückwärtskompatibel ... Ich habe das nicht eingebaut Logik in meine Lösung. Es interessiert mich nur, dass mein Ding mit dem neuesten Java funktioniert. –