2010-01-06 21 views
13

में वैश्विक चर बनाने के लिए कैसे मैं पैकेट फ़िल्टर करने के लिए एक ejabberd मॉड्यूल लिख रहा हूँ। मुझे gen_mod:get_module_opt() का उपयोग करके कुछ कॉन्फ़िगरेशन खींचने के लिए होस्टनाम प्राप्त करने की आवश्यकता है।एरलांग

मैं 4 महत्वपूर्ण कार्य है:

  1. start(Host, _Opt): यह मेरा मॉड्यूल लोड करने के लिए एक ejabberd कार्य है। मुझे Host परमाणु
  2. filter_packet({From, To, XML}) प्राप्त होता है: यह मेरा पैकेट फ़िल्टर हुक है। मैं इस समारोह में कस्टम पैरा नहीं पारित कर सकता हूं, क्योंकि यह ejabberd में एक हुक है।
  3. get_translation(XmlData): filter_packet() एक पाश
  4. fetch_translation(XmlData) में get_translation() कॉल: get_translation() से रिकर्सिवली कहा जाता है। यह वह जगह है जहां मैं gen_mod:get_module_opt() पर कॉल कर रहा हूं, और इसलिए Host की आवश्यकता है।

मेरा प्रश्न है, ताकि fetch_translation भी पहुंच सकते हैं कि कैसे मैं start() से Host लेने के लिए और एक वैश्विक चर में रख सकते हैं?

उत्तर

9

नामित ets तालिका बनाने और इसे वहां रखने का "सबसे आसान तरीका" है।

start(Host, _Opt) -> 
    ets:new(my_table, [named_table, protected, set, {keypos, 1}]), 
    ets:insert(my_table, {host, Host}), 
    ... 

fetch_translation(XmlData) -> 
    [{_, Host}] = ets:lookup(my_table, host), 
    ... 

ध्यान दें कि यह एक "सामान्य" समाधान है। Ejabberd आप जो चाहते हैं उसके लिए सुविधाएं प्रदान कर सकते हैं, लेकिन मैं इसके साथ आपकी मदद नहीं कर सकता।

+0

Thx जेड। मॉड्यूल ठीक से संकलित करता है लेकिन 'ets: new (my_table, [name_table, संरक्षित, सेट, {keypos, 1}]) के लिए' बैडगा 'त्रुटि देता है,' – Adil

+0

यदि तालिका 'my_table' मौजूद है, तो आपको एक बैडगा मिलेगा । आपको या तो जांचने की आवश्यकता है कि तालिका पहले से मौजूद है या नहीं, इसे एक कोशिश-पकड़ ब्लॉक – Zed

+0

में लपेटें, मैं ऊपर दिए गए को छोड़कर कहीं भी 'my_table' नहीं बना रहा हूं। – Adil

1

आप एक नया संदेश फ़िल्टरिंग प्रक्रिया शुरू कर सकते हैं और इसे erlang:register/2 का उपयोग करके पंजीकृत कर सकते हैं, फिर सभी filter_packet/1 इसके माध्यम से अनुरोध (संभावित बाधा) को रूट करें।

-define(?SERVER, msg_filter). 

start(Host, Opt) -> 
    {ok, Pid} = spawn(?MODULE, filter_loop, [Host, Opt]), 
    register(?SERVER, Pid). 

filter_loop(Host, Opt) -> 
    receive 
     {Pid, filter_packet, {_From, _To, XML}} -> 
      Trans = get_translation(XML, Host), 
      Pid ! {?SERVER, translation, Trans}, 
      filter_loop(Host, Opt) 
    end. 

filter_packet(Pack) -> 
    ?SERVER ! {self(), filter_packet, Pack} 
    receive 
     {?SERVER, translation, Trans} -> 
      % wrap translation 
      UpdatedPacket 
    end. 
1

कहें कि आप इनकमिंग पैकेट को फ़िल्टर कर रहे हैं, तो # jid.lserver आपके होस्ट हो सकता है।

+0

हाय एंडी 5। क्या आप समझा सकते हैं कि "to # jid.lserver" का अर्थ क्या है। मैं इसे कैसे सेट/प्राप्त कर सकता हूं? – Adil

+0

यह केवल सबसे अच्छा अनुमान है, लेकिन मुझे लगता है कि एक प्रकार का चर प्रकार के रिकॉर्ड के लिए बाध्य है (नीचे/src में jlib.hrl में रिकॉर्ड परिभाषा देखें)। # Jid.lserver का अर्थ है कि आप रिकॉर्ड के lserver फ़ील्ड तक पहुंचना चाहते हैं, जहां lserver jid के डोमेन का निम्न-संस्करण वाला संस्करण है। यदि आपको खोल में समस्याएं हैं, तो rd (jid, {user, [...]} चलाएं)। – andi5

1

अपने विवरण के लिए अनुमान लगाने के बजाय आप एक एकल डोमेन ejabberd तैनाती (कोई आभासी मेजबान) में हैं,

यो? Myname मैक्रो का उपयोग स्थानीय XMPP डोमेन प्राप्त कर सकते हैं (परिभाषा के लिए ejabberd.hrl देखें)।

9

यह एक ओवरकिल के रूप में लग सकता है लेकिन आप एक बहुत ही बुनियादी gen_server को लागू करने पर विचार कर सकते हैं। इसमें एक ऐसा राज्य शामिल है जो इसके कॉलबैक के लिए उपलब्ध है और डेटा वहां रखा जा सकता है। आपके मामले के लिए आप एक मॉड्यूल इस एक के लिए इसी तरह लिख सकते हैं:

-module(your_module_name). 

-behaviour(gen_server). 
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). 

-export([start/2, filter_loop/1]). 

start(Host, Opt) -> 
    %% start the named gen server 
    gen_server:start({local, ?MODULE}, ?MODULE, Host, []). 

filter_packet({From, To, XML}) -> 
    %% do your thing 
    gen_server:call(?MODULE, {fetch_translation, XmlData}). 

%% this will be called by gen_server:start - just pass the Host 
init(Host) -> 
    {ok, Host}. 

handle_call({fetch_translation, XmlData}, _From, Host) -> 
    %% do your thing 
    {reply, ok, Host}. 

%% you can ignore the rest - they are needed to be present 
handle_cast(_Msg, State) -> 
    {noreply, State}. 
handle_info(_Info, State) -> 
    {noreply, State}. 
code_change(_OldVsn, State, _Extra) -> 
    {ok, State}. 
1

आप अपने मॉड्यूल शीर्ष पर अपने वैश्विक चर को परिभाषित ...

नीचे
-define (Your Variable, "your host name here"). 

जैसे जैसे।

-define (RelayHost, "smtp.gmail.com"). 

और आप अपने मॉड्यूल में अपनी सभी विधियों में इस ग्लोबल वैरिएबल का उपयोग कर सकते हैं।

io:fwrite("Global Value ~p", [?RelayHost]). 

-AjAy

+4

-define चर परिभाषित नहीं करता है। यह संकलन-समय स्थिरांक को परिभाषित करता है। –

+0

फिर वैश्विक चर को परिभाषित करने के लिए कैसे? धन्यवाद –

+0

वैश्विक चर को परिभाषित करना संभव नहीं है। –