Java Language
दूरस्थ विधि मंगलाचरण (RMI)
खोज…
टिप्पणियों
RMI को 3 घटकों की आवश्यकता होती है: क्लाइंट, सर्वर और एक साझा दूरस्थ इंटरफ़ेस। साझा रिमोट इंटरफ़ेस क्लाइंट-सर्वर अनुबंध को उन तरीकों को निर्दिष्ट करके परिभाषित करता है जिन्हें सर्वर को लागू करना चाहिए। इंटरफ़ेस को सर्वर पर दिखाई देना चाहिए ताकि यह विधियों को लागू कर सके; इंटरफ़ेस क्लाइंट को दिखाई देना चाहिए ताकि यह पता चले कि सर्वर कौन से तरीके ("सेवाएं") प्रदान करता है।
रिमोट इंटरफ़ेस को लागू करने वाली कोई भी वस्तु सर्वर की भूमिका लेने के लिए नियत है। जैसे, क्लाइंट-सर्वर रिलेशनशिप, जिसमें सर्वर क्लाइंट में तरीकों का भी आह्वान कर सकता है, वास्तव में सर्वर-सर्वर रिलेशनशिप है। इसे कॉलबैक कहा जाता है क्योंकि सर्वर "क्लाइंट" को वापस कॉल कर सकता है। इसे ध्यान में रखते हुए, यह सर्वर के लिए पदनाम क्लाइंट का उपयोग करने के लिए स्वीकार्य है जो इस तरह से कार्य करता है।
साझा रिमोट इंटरफ़ेस Remote
विस्तार देने वाला कोई भी इंटरफ़ेस है। एक वस्तु जो सर्वर के रूप में कार्य करती है वह निम्नलिखित होती है:
- साझा दूरस्थ इंटरफ़ेस को लागू करता है, या तो स्पष्ट रूप से या अंतर्निहित रूप से
UnicastRemoteObject
को लागूUnicastRemoteObject
जोRemote
लागू करता है। - निर्यात किया गया है, या तो स्पष्ट रूप से यदि यह
UnicastRemoteObject
विस्तारितUnicastRemoteObject
, या स्पष्ट रूप सेUnicastRemoteObject#exportObject
पारित किया जा रहा है। - एक रजिस्ट्री में बाँधा गया, या तो सीधे
Registry
माध्यम से या अप्रत्यक्ष रूप सेNaming
माध्यम से। यह केवल प्रारंभिक संचार स्थापित करने के लिए आवश्यक है क्योंकि आगे के स्टब को सीधे आरएमआई के माध्यम से पारित किया जा सकता है।
प्रोजेक्ट सेटअप में, क्लाइंट और सर्वर प्रोजेक्ट पूरी तरह से असंबंधित होते हैं, लेकिन प्रत्येक इसके निर्माण पथ में एक साझा प्रोजेक्ट को निर्दिष्ट करता है। साझा प्रोजेक्ट में दूरस्थ इंटरफ़ेस होते हैं।
क्लाइंट-सर्वर: एक JVM में दूसरे से तरीकों को लागू करना
साझा दूरस्थ इंटरफ़ेस:
package remote;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RemoteServer extends Remote {
int stringToInt(String string) throws RemoteException;
}
साझा दूरस्थ इंटरफ़ेस को लागू करने वाला सर्वर:
package server;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import remote.RemoteServer;
public class Server implements RemoteServer {
@Override
public int stringToInt(String string) throws RemoteException {
System.out.println("Server received: \"" + string + "\"");
return Integer.parseInt(string);
}
public static void main(String[] args) {
try {
Registry reg = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
Server server = new Server();
UnicastRemoteObject.exportObject(server, Registry.REGISTRY_PORT);
reg.rebind("ServerName", server);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
ग्राहक सर्वर पर एक विधि लागू करना (दूर से):
package client;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import remote.RemoteServer;
public class Client {
static RemoteServer server;
public static void main(String[] args) {
try {
Registry reg = LocateRegistry.getRegistry();
server = (RemoteServer) reg.lookup("ServerName");
} catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
Client client = new Client();
client.callServer();
}
void callServer() {
try {
int i = server.stringToInt("120");
System.out.println("Client received: " + i);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
आउटपुट:
सर्वर प्राप्त: "120"
ग्राहक प्राप्त: 120
कॉलबैक: "क्लाइंट" पर तरीकों को लागू करना
अवलोकन
इस उदाहरण में 2 क्लाइंट सर्वर के माध्यम से एक दूसरे को जानकारी भेजते हैं। एक क्लाइंट सर्वर को एक नंबर भेजता है जो दूसरे क्लाइंट से रिलेटेड होता है। दूसरा क्लाइंट नंबर को आधा कर देता है और सर्वर के माध्यम से पहले क्लाइंट को वापस भेज देता है। पहला क्लाइंट वही करता है। सर्वर संचार बंद कर देता है जब संख्या किसी भी क्लाइंट द्वारा उस पर लौटा दी जाती है। 10. सर्वर से क्लाइंट के लिए वापसी मूल्य (वह संख्या जो स्ट्रिंग प्रतिनिधित्व में परिवर्तित हो गई) तब प्रक्रिया वापस आ जाती है।
- एक लॉगिन सर्वर खुद को एक रजिस्ट्री से बांधता है।
- एक ग्राहक लॉगिन सर्वर को देखता है और अपनी जानकारी के साथ
login
विधि कहता है। फिर:- लॉगिन सर्वर क्लाइंट जानकारी संग्रहीत करता है। इसमें कॉलबैक विधियों के साथ क्लाइंट का स्टब शामिल है।
- लॉगिन सर्वर क्लाइंट को स्टोर करने के लिए सर्वर स्टब ("कनेक्शन" या "सत्र") बनाता है और लौटाता है। इसमें सर्वर के स्टब में
logout
विधि (इस उदाहरण में अप्रयुक्त) सहित अपने तरीके शामिल हैं।
- एक क्लाइंट प्राप्तकर्ता के नाम और एक
int
साथ सर्वर केpassInt
को कॉल करता है। - सर्वर उस
int
साथ प्राप्तकर्ता क्लाइंट परhalf
कॉल करता है। यह सर्वर द्वारा बंद किए जाने तक एक बैक-एंड-आगे (कॉल और कॉलबैक) संचार शुरू करता है।
साझा दूरस्थ इंटरफ़ेस
लॉगिन सर्वर:
package callbackRemote;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RemoteLogin extends Remote {
RemoteConnection login(String name, RemoteClient client) throws RemoteException;
}
सर्वर:
package callbackRemote;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RemoteConnection extends Remote {
void logout() throws RemoteException;
String passInt(String name, int i) throws RemoteException;
}
ग्राहक:
package callbackRemote;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RemoteClient extends Remote {
void half(int i) throws RemoteException;
}
कार्यान्वयन
लॉगिन सर्वर:
package callbackServer;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
import callbackRemote.RemoteClient;
import callbackRemote.RemoteConnection;
import callbackRemote.RemoteLogin;
public class LoginServer implements RemoteLogin {
static Map<String, RemoteClient> clients = new HashMap<>();
@Override
public RemoteConnection login(String name, RemoteClient client) {
Connection connection = new Connection(name, client);
clients.put(name, client);
System.out.println(name + " logged in");
return connection;
}
public static void main(String[] args) {
try {
Registry reg = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
LoginServer server = new LoginServer();
UnicastRemoteObject.exportObject(server, Registry.REGISTRY_PORT);
reg.rebind("LoginServerName", server);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
सर्वर:
package callbackServer;
import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.Unreferenced;
import callbackRemote.RemoteClient;
import callbackRemote.RemoteConnection;
public class Connection implements RemoteConnection, Unreferenced {
RemoteClient client;
String name;
public Connection(String name, RemoteClient client) {
this.client = client;
this.name = name;
try {
UnicastRemoteObject.exportObject(this, Registry.REGISTRY_PORT);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void unreferenced() {
try {
UnicastRemoteObject.unexportObject(this, true);
} catch (NoSuchObjectException e) {
e.printStackTrace();
}
}
@Override
public void logout() {
try {
UnicastRemoteObject.unexportObject(this, true);
} catch (NoSuchObjectException e) {
e.printStackTrace();
}
}
@Override
public String passInt(String recipient, int i) {
System.out.println("Server received from " + name + ":" + i);
if (i < 10)
return String.valueOf(i);
RemoteClient client = LoginServer.clients.get(recipient);
try {
client.half(i);
} catch (RemoteException e) {
e.printStackTrace();
}
return String.valueOf(i);
}
}
ग्राहक:
package callbackClient;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import callbackRemote.RemoteClient;
import callbackRemote.RemoteConnection;
import callbackRemote.RemoteLogin;
public class Client implements RemoteClient {
RemoteConnection connection;
String name, target;
Client(String name, String target) {
this.name = name;
this.target = target;
}
public static void main(String[] args) {
Client client = new Client(args[0], args[1]);
try {
Registry reg = LocateRegistry.getRegistry();
RemoteLogin login = (RemoteLogin) reg.lookup("LoginServerName");
UnicastRemoteObject.exportObject(client, Integer.parseInt(args[2]));
client.connection = login.login(client.name, client);
} catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
if ("Client1".equals(client.name)) {
try {
client.connection.passInt(client.target, 120);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void half(int i) throws RemoteException {
String result = connection.passInt(target, i / 2);
System.out.println(name + " received: \"" + result + "\"");
}
}
उदाहरण चल रहा है:
- लॉगिन सर्वर चलाएँ।
- क्लाइंट के साथ तर्क क्लाइंट 2 क्लाइंट 1
Client2 Client1 1097
चलाएं। - क्लाइंट के साथ तर्क क्लाइंट 1 क्लाइंट 2
Client1 Client2 1098
चलाएं।
आउटपुट 3 कंसोल में दिखाई देंगे क्योंकि 3 JVM हैं। यहाँ उन्हें एक साथ पाला जाता है:
Client2 ने लॉग इन किया
Client1 ने लॉग इन किया
Client1: 120 से प्राप्त सर्वर
Client2: 60 से प्राप्त सर्वर
Client1: 30 से प्राप्त सर्वर
Client2: 15 से प्राप्त सर्वर
Client1: 7 से प्राप्त सर्वर
Client1 ने प्राप्त किया: "7"
Client2 ने प्राप्त किया: "15"
Client1 ने प्राप्त किया: "30"
Client2 ने प्राप्त किया: "60"
क्लाइंट और सर्वर कार्यान्वयन के साथ सरल आरएमआई उदाहरण
यह पांच जावा वर्गों और दो पैकेजों, सर्वर और क्लाइंट के साथ एक सरल आरएमआई उदाहरण है।
सर्वर पैकेज
PersonListInterface.java
public interface PersonListInterface extends Remote
{
/**
* This interface is used by both client and server
* @return List of Persons
* @throws RemoteException
*/
ArrayList<String> getPersonList() throws RemoteException;
}
PersonListImplementation.java
public class PersonListImplementation
extends UnicastRemoteObject
implements PersonListInterface
{
private static final long serialVersionUID = 1L;
// standard constructor needs to be available
public PersonListImplementation() throws RemoteException
{}
/**
* Implementation of "PersonListInterface"
* @throws RemoteException
*/
@Override
public ArrayList<String> getPersonList() throws RemoteException
{
ArrayList<String> personList = new ArrayList<String>();
personList.add("Peter Pan");
personList.add("Pippi Langstrumpf");
// add your name here :)
return personList;
}
}
Server.java
public class Server {
/**
* Register servicer to the known public methods
*/
private static void createServer() {
try {
// Register registry with standard port 1099
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
System.out.println("Server : Registry created.");
// Register PersonList to registry
Naming.rebind("PersonList", new PersonListImplementation());
System.out.println("Server : PersonList registered");
} catch (final IOException e) {
e.printStackTrace();
}
}
public static void main(final String[] args) {
createServer();
}
}
ग्राहक पैकेज
PersonListLocal.java
public class PersonListLocal {
private static PersonListLocal instance;
private PersonListInterface personList;
/**
* Create a singleton instance
*/
private PersonListLocal() {
try {
// Lookup to the local running server with port 1099
final Registry registry = LocateRegistry.getRegistry("localhost",
Registry.REGISTRY_PORT);
// Lookup to the registered "PersonList"
personList = (PersonListInterface) registry.lookup("PersonList");
} catch (final RemoteException e) {
e.printStackTrace();
} catch (final NotBoundException e) {
e.printStackTrace();
}
}
public static PersonListLocal getInstance() {
if (instance == null) {
instance = new PersonListLocal();
}
return instance;
}
/**
* Returns the servers PersonList
*/
public ArrayList<String> getPersonList() {
if (instance != null) {
try {
return personList.getPersonList();
} catch (final RemoteException e) {
e.printStackTrace();
}
}
return new ArrayList<>();
}
}
PersonTest.java
public class PersonTest
{
public static void main(String[] args)
{
// get (local) PersonList
ArrayList<String> personList = PersonListLocal.getInstance().getPersonList();
// print all persons
for(String person : personList)
{
System.out.println(person);
}
}
}
अपने आवेदन का परीक्षण करें
- Server.java की मुख्य विधि शुरू करें। आउटपुट:
Server : Registry created.
Server : PersonList registered
- PersonTest.java की मुख्य विधि शुरू करें। आउटपुट:
Peter Pan
Pippi Langstrumpf