2017-02-27 8 views
10

में अलग app से मॉड्यूल सुई मैं दो नोड क्षुधा/सेवाओं है कि एक साथ चल रहे हैं, 1. मुख्य एप्लिकेशन 2. दूसरा एप्लिकेशन हैकैसे Node.js

मुख्य एप्लिकेशन को सभी को दिखाने के लिए जिम्मेदार है अंत में अलग-अलग ऐप्स से डेटा। अब मैं मुख्य ऐप में दूसरे ऐप का कुछ कोड डालता हूं और अब यह काम कर रहा है, लेकिन मैं इसे डीकॉप्लेड करना चाहता हूं। मेरा मतलब है कि सेकनोड ऐप का कोड मुख्य ऐप में नहीं होगा (किसी भी तरह से इसे रनटाइम पर इंजेक्ट करने के लिए)

दूसरी सेवा की तरह मुख्य ऐप में इसके कोड को इंजेक्ट करने के लिए पंजीकृत किया गया है। इसका कोड केवल दो मॉड्यूल है, क्या यह नोडजेज़ में करना संभव है?

const Socket = require('socket.io-client'); 
const client = require("./config.json"); 

module.exports = (serviceRegistry, wsSocket) =>{ 
    var ws = null; 
    var consumer =() => { 
     var registration = serviceRegistry.get("tweets"); 
     console.log("Service: " + registration); 
     //Check if service is online 
     if (registration === null) { 
      if (ws != null) { 
       ws.close(); 
       ws = null; 
       console.log("Closed websocket"); 
      } 
      return 
     } 
     var clientName = `ws://localhost:${registration.port}/` 
     if (client.hosted) { 
      clientName = `ws://${client.client}/`; 
     } 
     //Create a websocket to communicate with the client 
     if (ws == null) { 
      console.log("Created"); 
      ws = Socket(clientName, { 
       reconnect: false 
      }); 
      ws.on('connect',() => { 
       console.log("second service is connected"); 
      }); 
      ws.on('tweet', function (data) { 
       wsSocket.emit('tweet', data); 
      }); 
      ws.on('disconnect',() => { 
       console.log("Disconnected from blog-twitter") 
      }); 
      ws.on('error', (err) => { 
       console.log("Error connecting socket: " + err); 
      }); 
     } 
    } 
    //Check service availability 
    setInterval(consumer, 20 * 1000); 
} 

मुख्य मॉड्यूल मैं इस कोड डाल में और मैं द्वारा यह दसगुणा क्रम पर किसी भी तरह यह इंजेक्षन करना चाहते हैं? उदाहरण बहुत उपयोगी होगा ...

+0

क्यों मॉड्यूल के रूप में अपने दूसरे ऐप निर्यात नहीं, तो यू अपने मुख्य अनुप्रयोग में आयात कर सकते हैं। – Xlee

+0

_ "किसी भी तरह से इसे रनटाइम पर इंजेक्ट करने के लिए" _। इसे 'आवश्यकता() 'कहा जाता है। – robertklep

+0

क्या आप इसे पाने के अपने कारणों को स्पष्ट कर सकते हैं? जैसा कि कुछ उत्तरों में वर्णित है decoupling इसे पूरा करने का तरीका है। जब तक आप ऐसा करने के लिए एक मजबूत कारण नहीं रखते हैं, तो मैं कहूंगा कि आप कुछ डिकूप्लेड - माइक्रो-सर्विसेज, पब/सब, जॉब कतार या यहां तक ​​कि एक संवाददाता द्वारा खपत के लिए डेटा लॉगिंग करने से बेहतर हैं। – Brian

उत्तर

4

आप इस लक्ष्य को हासिल करने के लिए vm मॉड्यूल का उपयोग करना होगा। https://nodejs.org/api/vm.html पर अधिक तकनीकी जानकारी। मुझे बताएं कि आप इसका उपयोग कैसे कर सकते हैं:

  1. आप कोड से संकलित जेएस कोड बनाने के लिए एपीआई vm.script का उपयोग कर सकते हैं जिसे आप बाद में चलाने के लिए चाहते हैं। एक नया vm.Script वस्तु बनाना आधिकारिक दस्तावेज

से विवरण देखें कोड को संकलित करता है, लेकिन यह नहीं चलता है। संकलित vm.Script कई बार बाद में चलाया जा सकता है। पर ध्यान देना महत्वपूर्ण है कि कोड किसी भी वैश्विक वस्तु से बंधे नहीं है; बल्कि, यह प्रत्येक रन से पहले बाध्य है, बस उस दौड़ के लिए।

  1. अब जब आप डालने या इस कोड को चलाना चाहते हैं, तो आप script.runInContext एपीआई का उपयोग कर सकते हैं।

उनके आधिकारिक दस्तावेज से एक और अच्छा उदाहरण:

'use strict'; 
const vm = require('vm'); 

let code = 
`(function(require) { 

    const http = require('http'); 

    http.createServer((request, response) => { 
    response.writeHead(200, {'Content-Type': 'text/plain'}); 
    response.end('Hello World\\n'); 
    }).listen(8124); 

    console.log('Server running at http://127.0.0.1:8124/'); 
})`; 

vm.runInThisContext(code)(require); 

फ़ाइल जे एस का उपयोग कर सीधे का एक और उदाहरण:

var app = fs.readFileSync(__dirname + '/' + 'app.js'); 
vm.runInThisContext(app); 

आप सशर्त कोड है जो आप सम्मिलित करना चाहते के लिए इस दृष्टिकोण का उपयोग कर सकते हैं ।

5

आप अपने किसी एक ऐप से पैकेज बना सकते हैं और फिर दूसरे ऐप में पैकेज का संदर्भ दे सकते हैं।

https://docs.npmjs.com/getting-started/creating-node-modules

+0

धन्यवाद लेकिन इसे decoupled किया जाना चाहिए, यहां आपको इसे आवश्यकतानुसार रखना चाहिए .... –

+0

यह आपको लगता है कि यह इतना आसान नहीं है ... :) –

+0

मैं सहमत हूं, आसान नहीं। लेकिन decoupling अच्छा है। – paqash

2

दो अनुप्रयोगों को रद्द करने के कई तरीके हैं। पब/उप पैटर्न (यदि आपको प्रतिक्रिया की आवश्यकता नहीं है) के साथ एक आसान तरीका है।
(अब अगर आप बहुत जोड़ी है कि एक आवेदन पत्र है, यह बहुत यह दसगुणा जब तक आप कुछ पुनर्रचना करना कठिन हो जाएगा।)
zeromq पब/उप का एक बहुत अच्छा कार्यान्वयन प्रदान करता है और बहुत तेजी से है।
उदा।

import zmq from "zmq"; 
socket.connect('tcp://127.0.0.1:5545'); 
socket.subscribe('sendConfirmation'); 

socket.on('message', function (topic, message) { 
    // you can get the data from message. 
    // something like: 
    const msg = message.toString('ascii'); 
    const data = JSON.parse(msg); 
    // do some actions. 
    // ..... 

}); 

//don't forget to close the socket. 
process.on('SIGINT',() => { 
    debug("... closing the socket ...."); 
    socket.close(); 
    process.exit(); 
}); 

//----------------------------------------- 
import zmq from "zmq"; 
socket.bind('tcp://127.0.0.1:5545'); 
socket.send(['sendConfirmation', someData]); 

process.on('SIGINT', function() { 
    socket.close(); 
}); 

इस तरह आप दो अलग-अलग कंटेनर (डोकर) अपने मॉड्यूल के लिए, हो सकता है सिर्फ इसी बंदरगाह खोलने के लिए सुनिश्चित करें।
जो मुझे समझ में नहीं आता है, यही कारण है कि आप wsSocket इंजेक्ट करते हैं और आप एक नई सॉकेट भी बनाते हैं। शायद मैं क्या होगा बस सॉकेट आईडी भेजने के लिए है, और फिर बस इसे पसंद का उपयोग करें:

const _socketId = "/#" + data.socketId;  
io.sockets.connected[socketId].send("some message"); 

तुम भी, जैसे काफ्का zmq के बजाय एक और समाधान इस्तेमाल कर सकते हैं सिर्फ विचार है कि धीमी है लेकिन यह लॉग रखेगा।
आशा है कि यह आपको आपकी समस्या को हल करने का विचार प्राप्त कर सकता है।

2

आप एनपीएम लिंक सुविधा का उपयोग कर सकते हैं।

  1. मॉड्यूल के रूट फ़ोल्डर
  2. में NPM लिंक चल चलाकर अपने लक्ष्य मॉड्यूल (एप्लिकेशन) में जुड़े हुए मॉड्यूल स्थापित करके एक वैश्विक कड़ी के रूप में एक मॉड्यूल की घोषणा:

    लिंक करने की प्रक्रिया दो चरणों के होते हैं लक्ष्य फ़ोल्डर

यह एनपीएम लिंक तब तक बहुत अच्छी तरह से काम करता है जब तक कि आपके स्थानीय मॉड्यूल में से कोई एक अन्य स्थानीय मॉड्यूल पर निर्भर न हो। इस मामले में, लिंकिंग विफल रहता है क्योंकि यह निर्भर मॉड्यूल नहीं ढूंढ सकता है। इस समस्या को हल करने के लिए, किसी को निर्भर मॉड्यूल को पैरेंट मॉड्यूल से लिंक करने की आवश्यकता है और उसके बाद माता-पिता को ऐप में इंस्टॉल करना होगा।

https://docs.npmjs.com/cli/link