"हाय! और एक और खुशी का विषय: आरएमआई। आरएमआई रिमोट मेथड इनवोकेशन के लिए खड़ा है । दूसरे शब्दों में, आरएमआई एक ऐसा तंत्र है जो एक जावा मशीन से एक ऑब्जेक्ट को दूसरी जावा मशीन से ऑब्जेक्ट पर तरीकों को कॉल करने की अनुमति देता है , भले ही वे अलग-अलग हों। कंप्यूटर, अलग-अलग देशों में, या दुनिया के अलग-अलग हिस्सों में।"

आरएमआई - 1

"वाह! यह बहुत अच्छा लगता है।"

"हाँ। लेकिन मैं आपको केवल एक सिंहावलोकन देने की कोशिश करूँगा। इसके साथ, यदि आप बहुत गहराई तक जाते हैं, तो आप इसकी बारीकियों से भ्रमित हो सकते हैं कि यह कैसे काम करता है।"

"लेकिन अगर आप चरम पर नहीं जाते हैं, तो आरएमआई न केवल बहुत सरल है, बल्कि यह एक प्रोग्रामर के जीवन को भी बहुत सरल करता है। जिसके लिए, हम इसे अपना गहरा सम्मान देते हैं।"

"इसलिए, हम चाहते हैं कि जावा प्रोग्राम में एक ऑब्जेक्ट किसी अन्य जावा प्रोग्राम में किसी ऑब्जेक्ट पर एक विधि को कॉल करे। भले ही ये प्रोग्राम कहां चल रहे हों।"

"आइए सबसे सरल उदाहरण पर विचार करें: जब दोनों प्रोग्राम एक ही कंप्यूटर पर चल रहे हों।  प्रोग्राम को इंटरनेट पर इंटरैक्ट करने की अनुमति देने के लिए, आपको JVM की अनुमतियों को कॉन्फ़िगर करने की आवश्यकता है , लेकिन आज हम उसे कवर नहीं करेंगे।"

"जावा में, आप दूरस्थ रूप से केवल इंटरफेस के तरीकों को कॉल कर सकते हैं, कक्षाओं को नहीं।"

"तो, हमारे पास दो कार्यक्रम हैं। वे एक दूसरे के तरीकों को कैसे कॉल कर सकते हैं?"

"आइए उस स्थिति पर विचार करें जहां एक प्रोग्राम में एक ऑब्जेक्ट होता है, और दूसरा प्रोग्राम उस ऑब्जेक्ट पर विधियों को कॉल करना चाहता है। चलिए पहले प्रोग्राम को सर्वर कहते हैं, और दूसरा - क्लाइंट। "

"पहले, मैं कुछ नमूना कोड प्रदान करूँगा, और फिर हम इसका विश्लेषण करेंगे।"

"तो हमारा कार्यक्रम क्या करेगा?"

"हम्म। सरलता के लिए, कार्यक्रम में एक विधि होगी जो इसे पास की गई स्ट्रिंग को उलट देती है।"

"काफी सरल।"

"अच्छा, तो चलिए शुरू करते हैं:"

"सबसे पहले, हमें एक इंटरफ़ेस की आवश्यकता है जो हमारी आवश्यकताओं को पूरा करे:"

कार्यक्रमों के बीच संचार के लिए इंटरफ़ेस
interface Reverse extends Remote
{
 public String reverse(String str) throws RemoteException;
}

"मैंने एक रिवर्स इंटरफ़ेस बनाया और उसमें एक रिमोट मार्कर इंटरफ़ेस जोड़ा, साथ ही साथ एक रिमोटएक्सेप्शन भी। विधि को कॉल करने पर अप्रत्याशित त्रुटियाँ हो सकती हैं। यदि कोई करता है, तो यह अपवाद फेंक दिया जाएगा।"

"अब हमें एक सर्वर क्लास लिखने की जरूरत है जो इस इंटरफेस को लागू करता है:"

सर्वर के लिए वर्ग
class ReverseImpl implements Reverse
{
 public String reverse(String str) throws RemoteException
 {
  return new StringBuffer(str).reverse().toString();
 }
}

"ठीक है। हम इस विधि में स्ट्रिंग को उल्टा करते हैं।"

"हां।"

"अब हमें इस ऑब्जेक्ट को दूसरे प्रोग्राम से कॉल करने योग्य बनाने की आवश्यकता है। यहां बताया गया है कि आप यह कैसे करते हैं:"

वस्तु साझा करना
public static final String UNIC_BINDING_NAME = "server.reverse";

public static void main(String[] args) throws Exception
{
 // Create an object to be accessible remotely.
 final ReverseImpl service = new ReverseImpl();

 // Create a registry of shared objects.
 final Registry registry = LocateRegistry.createRegistry(2099);
 // Create a stub for receiving remote calls.
 Remote stub = UnicastRemoteObject.exportObject(service, 0);
 // Register the stub in the registry.
 registry.bind(UNIC_BINDING_NAME, stub);

 // Put the main thread to sleep, or else the program will exit.
 Thread.sleep(Integer.MAX_VALUE);
}

"मैं इस लाइन को लाइन से समझाऊंगा।"

" पंक्ति 1 में , हम UNIC_BINDING_NAME चर  में अपने दूरस्थ वस्तु (वस्तु जो दूरस्थ रूप से सुलभ है) के लिए एक अद्वितीय नाम (जिसे हमने बनाया है) संग्रहीत करते हैं। यदि प्रोग्राम कई वस्तुओं को सुलभ बनाता है, तो प्रत्येक का अपना अनूठा नाम होना चाहिए। हमारा ऑब्जेक्ट का अद्वितीय नाम 'server.reverse' है।"

" लाइन 6 पर हम एक ReverseImpl ऑब्जेक्ट बनाते हैं जो दूरस्थ रूप से एक्सेस किया जा सकेगा। इसके तरीकों को लागू किया जाएगा।"

" लाइन 9 पर हम एक विशेष वस्तु बनाते हैं जिसे रजिस्ट्री कहा जाता है। हमें उन वस्तुओं को पंजीकृत करने के लिए इसका उपयोग करने की आवश्यकता होती है जिन्हें हम साझा करते हैं। जेवीएम बाद में उनके साथ बातचीत करेगा। 2099 एक पोर्ट है (एक अद्वितीय संख्या जिसे अन्य प्रोग्राम हमारे एक्सेस करने के लिए उपयोग कर सकता है) ऑब्जेक्ट रजिस्ट्री)।"

"दूसरे शब्दों में, किसी ऑब्जेक्ट को एक्सेस करने के लिए, आपको ऑब्जेक्ट रजिस्ट्री के यूनिक नंबर (पोर्ट) और ऑब्जेक्ट के यूनिक नाम को जानने की जरूरत है, और रिमोट ऑब्जेक्ट द्वारा लागू किए गए इंटरफ़ेस के समान ही होना चाहिए।"

"अच्छा। कुछ इस तरह: फोन से कॉल करें (नंबर चाहिए) और बिल (वस्तु का नाम) के लिए पूछें?"

"हाँ। अब, चलते रहो।"

" पंक्ति 11 पर  , हम एक स्टब बनाते हैं। एक स्टब एक विशेष वस्तु है जो रिमोट कॉल के बारे में जानकारी प्राप्त करता है, इसे अनपैक करता है, विधि तर्कों को डीरिएरलाइज़ करता है, और आवश्यक विधि को कॉल करता है। फिर यह परिणाम या अपवाद को क्रमबद्ध करता है, यदि कोई था , और यह सब कॉल करने वाले को वापस भेज देता है।"

"मैं देख रहा हूँ। लगभग। आपने कहा था कि यह 'विधि तर्कों का वर्णन करता है'। तो, इसका मतलब है कि दूरस्थ विधियों के तर्क क्रमबद्ध होने चाहिए?"

"हाँ। आप उन्हें नेटवर्क पर और कैसे भेजेंगे? सच है, अपवाद हैं, यानी ऑब्जेक्ट जो संदर्भ द्वारा पारित किए जाते हैं, लेकिन आज हम उनके बारे में बात नहीं करेंगे।"

"हम इसे इस तरह रखेंगे: आप गैर-धारावाहिक वस्तुओं को पारित नहीं कर सकते हैं, लेकिन यदि आप वास्तव में चाहते हैं, तो आप कर सकते हैं। लेकिन यह एक दर्द है, आप जानते हैं।"

"ठीक है।"

"तो चलो चलते हैं।"

" लाइन 13 पर , हम रजिस्ट्री में एक अद्वितीय नाम के तहत अपनी वस्तु के स्टब को पंजीकृत करते हैं।"

" लाइन 16 पर , हम मुख्य थ्रेड को स्लीप में रखते हैं। सभी रिमोट कॉल अलग-अलग थ्रेड्स पर प्रोसेस किए जाते हैं। महत्वपूर्ण बात यह है कि प्रोग्राम चल रहा है। इसलिए हम मुख्य थ्रेड को यहां स्लीप करने के लिए रखते हैं। बस इतना ही।"

"ठीक है।"

"बहुत बढ़िया, तो यहाँ क्लाइंट का एक उदाहरण है:"

दूरस्थ वस्तु के साथ कार्य करना
public static final String UNIC_BINDING_NAME = "server.reverse";

public static void main(String[] args) throws Exception
{
 // Create a registry of shared objects
 final Registry registry = LocateRegistry.createRegistry(2099);

 // Get the object (actually, this is a proxy object)
 Reverse service = (Reverse) registry.lookup(UNIC_BINDING_NAME);

 // Call the remote method
 String result = service.reverse("Home sweet home.");
}

"मैं इस कोड को लाइन द्वारा समझाऊंगा:"

" पंक्ति 1  दूरस्थ वस्तु का अद्वितीय नाम है । यह क्लाइंट और सर्वर दोनों पर समान होना चाहिए।"

" पंक्ति 6 ​​में  , हम « रिमोट ऑब्जेक्ट्स की रजिस्ट्री » बनाते हैं। इसका पोर्ट (2099) सर्वर एप्लिकेशन के लिए रजिस्ट्री के पोर्ट के समान होना चाहिए।

" लाइन 9 पर , हम रजिस्ट्री से ऑब्जेक्ट प्राप्त करते हैं। लौटाई गई वस्तु एक प्रॉक्सी ऑब्जेक्ट है और एक इंटरफ़ेस में परिवर्तित हो जाती है। इंटरफ़ेस को रिमोट मार्कर इंटरफ़ेस इनहेरिट करना चाहिए।"

" लाइन 12 पर , हम इंटरफ़ेस के तरीकों को कहते हैं जैसे कि ऑब्जेक्ट उसी प्रोग्राम के भीतर बनाया गया था। इसमें कोई अंतर नहीं है।"

"कूल! अब मैं वितरित एप्लिकेशन लिख सकता हूं। या एंड्रॉइड के लिए बैटलशिप जैसे गेम।"

"तुम हिम्मत मत करो, अमीगो! एंड्रॉइड ऑपरेटिंग सिस्टम को 27 वीं शताब्दी में दुनिया पर कब्जा करने के अपने तीसरे प्रयास के बाद प्रतिबंधित कर दिया गया था। रोबोटों की इस तक कोई पहुंच नहीं है। आपको इससे दूर करने का कोई तरीका नहीं होगा आप चिल्लाना शुरू कर देंगे, «सभी मनुष्यों को मार डालो!»"

"हम्म। ठीक है। लेकिन मुझे अभी भी डिएगो से पूछना होगा। आप कभी नहीं जानते, शायद उसके पास इसके बारे में कहने के लिए कुछ दिलचस्प होगा।"

"तो जाओ उससे पूछो। ठीक है, ठीक है, कल तक।"

"अलविदा, ऋषि। दिलचस्प पाठ के लिए धन्यवाद।"