CodeGym /Java Blog /अनियमित /जावा आरएमआई
John Squirrels
स्तर 41
San Francisco

जावा आरएमआई

अनियमित ग्रुप में प्रकाशित
नमस्ते! आज हम एक दिलचस्प विषय पर विचार करेंगे: Java RMI। यह रिमोट मेथड इनवोकेशन के लिए है। आप दो प्रोग्रामों को एक दूसरे के साथ संवाद करने की अनुमति देने के लिए आरएमआई का उपयोग कर सकते हैं, भले ही वे अलग-अलग कंप्यूटरों पर हों। क्या वह अच्छा लगता है? :) और यह करना इतना मुश्किल नहीं है! आज के पाठ में, हम RMI इंटरैक्शन के तत्वों का विश्लेषण करेंगे और यह पता लगाएंगे कि इसे कैसे कॉन्फ़िगर किया जाए। पहली चीज जो हमें चाहिए वह क्लाइंट और सर्वर है। हमें वास्तव में कंप्यूटर शब्दावली में गहराई तक जाने की आवश्यकता नहीं है। जब RMI की बात आती है, तो ये केवल दो प्रोग्राम होते हैं। उनमें से एक में ऑब्जेक्ट शामिल होगा, और दूसरा उस ऑब्जेक्ट पर विधियों को कॉल करेगा। किसी भिन्न कार्यक्रम में मौजूद किसी वस्तु के कॉलिंग तरीके - अब यह कुछ ऐसा है जो हमने अभी तक नहीं किया है! इसे आजमाने का समय आ गया है! :) फंसने से बचने के लिए, चलो' आइए हमारे कार्यक्रम को सरल रखें। सामान्य तौर पर, एक सर्वर क्लाइंट द्वारा अनुरोधित कुछ गणना करता है। और इसलिए यह हमारे साथ होगा। हमारा सर्वर एक साधारण कैलकुलेटर प्रोग्राम होगा। इसका एक ही तरीका होगा:गुणा करें () । यह क्लाइंट प्रोग्राम द्वारा भेजे गए दो नंबरों को गुणा करेगा और फिर परिणाम लौटाएगा। सबसे पहले, हमें एक इंटरफ़ेस चाहिए:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {

   int multiply(int x, int y) throws RemoteException;
}
हमें इंटरफ़ेस की आवश्यकता क्यों है? क्योंकि आरएमआई प्रॉक्सी बनाने पर निर्भर करता है, जिसे आपने पिछले पाठों में पढ़ा था । जैसा कि आप शायद याद करते हैं, हम कक्षाओं के बजाय इंटरफेस के माध्यम से प्रॉक्सी के साथ काम करते हैं। हमारे इंटरफेस के लिए 2 महत्वपूर्ण आवश्यकताएं हैं!
  1. इसे दूरस्थ इंटरफ़ेस का विस्तार करना चाहिए।
  2. इसके सभी तरीकों को एक RemoteException फेंकना चाहिए (IDE इसे स्वचालित रूप से नहीं करेगा - आपको इसे मैन्युअल रूप से जोड़ने की आवश्यकता है!)
अब हमें एक सर्वर क्लास बनाने की जरूरत है जो हमारे कैलकुलेटर इंटरफेस को लागू करता है। अभ्यास में आरएमआई - 2यहाँ भी, सब कुछ काफी सरल है:

import java.rmi.RemoteException;

public class RemoteCalculationServer implements Calculator {

   @Override
   public int multiply(int x, int y) throws RemoteException {
       return x*y;
   }

}
यहां टिप्पणी करने के लिए वास्तव में कुछ भी नहीं है :) अब हमें एक सर्वर प्रोग्राम लिखने की आवश्यकता है जो हमारे कैलकुलेटर ऑब्जेक्ट को कॉन्फ़िगर और चलाएगा। यह ऐसा दिखाई देगा:

import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class ServerMain {

   public static final String UNIQUE_BINDING_NAME = "server.calculator";

   public static void main(String[] args) throws RemoteException, AlreadyBoundException, InterruptedException {

       final RemoteCalculationServer server = new RemoteCalculationServer();

       final Registry registry = LocateRegistry.createRegistry(2732);

       Remote stub = UnicastRemoteObject.exportObject(server, 0);
       registry.bind(UNIQUE_BINDING_NAME, stub);

       Thread.sleep(Integer.MAX_VALUE);

   }
}
आइए इसे समझते हैं :) पहली पंक्ति में, हम कुछ स्ट्रिंग चर घोषित करते हैं:

public static final String UNIQUE_BINDING_NAME = "server.calculator";
यह स्ट्रिंग दूरस्थ वस्तु का विशिष्ट नाम है। हमारा क्लाइंट प्रोग्राम हमारे सर्वर को खोजने के लिए इस नाम का उपयोग करता है: आप इसे बाद में देखेंगे। अगला, हम अपना कैलकुलेटर ऑब्जेक्ट बनाते हैं:

final RemoteCalculationServer server = new RemoteCalculationServer();
यहाँ सब कुछ स्पष्ट है। आगे जो आता है वह अधिक दिलचस्प है:

final Registry registry = LocateRegistry.createRegistry(2732);
यह रजिस्ट्री वस्तु दूरस्थ वस्तुओं की एक रजिस्ट्री है। ये ऐसे ऑब्जेक्ट हैं जिन्हें अन्य प्रोग्राम दूरस्थ रूप से एक्सेस कर सकते हैं :) हमने LocateRegistry.createRegistry() विधि को 2732 नंबर पास किया। यह पोर्ट नंबर है - एक अद्वितीय संख्या जो अन्य प्रोग्राम हमारी ऑब्जेक्ट रजिस्ट्री को खोजने के लिए उपयोग करेंगे (फिर से, आप इसे नीचे देखेंगे)। ठीक साथ चल रहा है... आइए देखें कि अगली पंक्ति में क्या होता है:

Remote stub = UnicastRemoteObject.exportObject(server, 0);
हम इस पंक्ति में एक स्टब बनाते हैं। एक स्टब पूरे रिमोट कॉल को इनकैप्सुलेट करता है। आप इसे RMI का सबसे महत्वपूर्ण तत्व मान सकते हैं। इससे क्या होता है?
  1. यह किसी विधि के दूरस्थ कॉल के बारे में सारी जानकारी प्राप्त करता है।
  2. यदि विधि में पैरामीटर हैं, तो स्टब उन्हें डिसेर्बलाइज़ करेगा। इस बिंदु पर ध्यान दें! आप जिन तर्कों को दूरस्थ रूप से कॉल करने वाले तरीकों से पास करते हैं, वे क्रमबद्ध होने चाहिए (आखिरकार, वे नेटवर्क पर प्रसारित किए जाएंगे)। यह हमारे लिए कोई समस्या नहीं है — हम केवल नंबर ट्रांसमिट कर रहे हैं। लेकिन अगर आप ऑब्जेक्ट ट्रांसमिट कर रहे हैं, तो इस आवश्यकता को न भूलें!
  3. उसके बाद, स्टब वांछित विधि को कॉल करता है।
हम अपने कैलकुलेटर सर्वर ऑब्जेक्ट को UnicastRemoteObject.exportObject() विधि से पास करते हैं। इस प्रकार हम इसके तरीकों को दूरस्थ रूप से कॉल करना संभव बनाते हैं। बस एक काम करना बाकी है:

registry.bind(UNIQUE_BINDING_NAME, stub);
हम अपने स्टब को रिमोट ऑब्जेक्ट रजिस्ट्री में उस नाम के तहत "रजिस्टर" करते हैं जिसे हमने शुरुआत में बनाया था। अब ग्राहक इसे ढूंढ पाएगा! शायद आपने ध्यान दिया हो कि हम कार्यक्रम के मुख्य सूत्र को अंत में सोने के लिए रखते हैं:

Thread.sleep(Integer.MAX_VALUE);
हमें बस सर्वर को लंबे समय तक चलाने की जरूरत है। IDE में, हम एक साथ दो main() मेथड लॉन्च करेंगे: पहला, सर्वर का main() मेथड ( ServerMain क्लास में, जिसे हमने पहले ही लिखा है), और दूसरा, क्लाइंट का main() मेथड ( ClientMain क्लास में, जिसे हम नीचे लिखेंगे)। यह महत्वपूर्ण है कि जब हम क्लाइंट शुरू करते हैं तो सर्वर प्रोग्राम समाप्त नहीं होता है, इसलिए हम इसे लंबे समय तक सोने के लिए रख देते हैं। किसी भी घटना में, यह चलता रहेगा :) अब हम अपने सर्वर की main() विधि चला सकते हैं। इसे चलने दें और क्लाइंट प्रोग्राम द्वारा किसी विधि को कॉल करने की प्रतीक्षा करें :) अब क्लाइंट प्रोग्राम लिखते हैं! यह गुणन के लिए हमारे सर्वर को नंबर भेजेगा।

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class ClientMain {

   public static final String UNIQUE_BINDING_NAME = "server.calculator";

   public static void main(String[] args) throws RemoteException, NotBoundException {

       final Registry registry = LocateRegistry.getRegistry(2732);

       Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);

       int multiplyResult = calculator.multiply(20, 30);

       System.out.println(multiplyResult);
   }
}
यह सरल दिखता है। लेकिन यहाँ क्या हो रहा है? सबसे पहले, ग्राहक को उस वस्तु का विशिष्ट नाम पता होना चाहिए जिसके तरीकों को वह दूरस्थ रूप से कॉल करेगा। तदनुसार, क्लाइंट प्रोग्राम में, हमने सार्वजनिक स्थैतिक अंतिम स्ट्रिंग UNIQUE_BINDING_NAME = "server.calculator"; चर। अगला, मुख्य () विधि में , हम दूरस्थ वस्तुओं के रजिस्टर तक पहुँच प्राप्त करते हैं। ऐसा करने के लिए, हमें LocateRegistry.getRegistry() मेथड को कॉल करना होगा और ServerMain प्रोग्राम में हमारी रजिस्ट्री बनाने के लिए उपयोग किए गए पोर्ट नंबर को पास करना होगा (पोर्ट 2732; यह नंबर सिर्फ एक उदाहरण है - आप एक अलग नंबर का उपयोग करके देख सकते हैं):

final Registry registry = LocateRegistry.getRegistry(2732);
अब हमें केवल रजिस्ट्री से वांछित वस्तु प्राप्त करने की आवश्यकता है! यह आसान है, क्योंकि हम इसका अनोखा नाम जानते हैं!

Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
टाइप कास्टिंग पर ध्यान दें। हम प्राप्त वस्तु को कैलक्यूलेटर इंटरफ़ेस में कास्ट करते हैं, RemoteCalculationServer वर्ग के लिए नहीं । जैसा कि हमने पाठ की शुरुआत में कहा था, आरएमआई एक प्रॉक्सी पर निर्भर करता है, इसलिए दूरस्थ कॉल केवल इंटरफ़ेस विधियों के लिए उपलब्ध हैं, न कि कक्षाओं के तरीकों के लिए। अंत में, हम दूरस्थ रूप से हमारे ऑब्जेक्ट पर गुणा () विधि को कॉल करते हैं और परिणाम को कंसोल पर आउटपुट करते हैं।

int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
सर्वरमेन वर्ग की मुख्य () विधि लंबे समय से चल रही है अब क्लाइंट प्रोग्राम ( ClientMain ) में main() विधि चलाने का समय आ गया है ! कंसोल आउटपुट:

600
इतना ही! हमारे कार्यक्रम (वास्तव में दो कार्यक्रम!) ने वही किया जो इसे करना चाहिए था :) यदि आपके पास समय और इच्छा है, तो आप इसे थोड़ा मसाला कर सकते हैं। उदाहरण के लिए, कैलकुलेटर को चार मानक अंकगणितीय परिचालनों का समर्थन करने दें, और संख्याओं को आदिम प्रकार के रूप में नहीं, बल्कि CalculationInstance(int x, int y) ऑब्जेक्ट के रूप में पास करें। अगले पाठ में मिलते हैं! :)
टिप्पणियां
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION