2009-02-09 29 views
7

इस MarshalByRef वर्ग को देखते हुए के दौरान ग्राहक की पहचान:एक .NET दूरस्थ मंगलाचरण

public class MyRemotedClass : MarshalByRef 
{ 
    public void DoThis() 
    { 
    ... 
    } 
    public void DoThat() 
    { 
    ... 
    } 
} 

क्लाइंट साइड कोड:

MyRemotedClass m = GetSomehowMyRemotedClass(); 
m.DoThis(); 
m.DoThat(); 

मैं एक ही समय में ही बात कर रहे कई ग्राहकों हो सकता है। मैं ग्राहकों को अलग करना चाहता हूं। मैं दूरस्थ रूप से एक्सेस किए गए तरीकों के अंदर कैसे पहचान सकता हूं, जिसके द्वारा रिमोटिंग आमंत्रण निष्पादित किया जाता है? उदाहरण के लिए, मैं लॉग इन कर सकता हूं कि किसने किया। (वास्तव में, मैं, वापस सही ग्राहक की जानकारी का पता लगाने की जरूरत नहीं है मैं सिर्फ ग्राहकों द्वारा समूह आमंत्रण करने में सक्षम होना चाहता हूँ।)

मैं कोड की भारी मात्रा में [अधिक पृष्ठभूमि जानकारी जोड़ने के लिए संपादित] संपत्तियों सहित, कवर करने के लिए। इसलिए इनपुट पैरामीटर सूची का विस्तार करना एक विकल्प नहीं है।

उत्तर

15

जिन्हें आप कर सकते में से एक एक IServerChannelSinkProvider को लागू करने से आईपी पते से एक ग्राहक की पहचान है।

अपने दूरस्थ होस्ट परियोजना के लिए इस वर्ग में जोड़ें:

ClientIPServerSinkProvider.cs

using System; 
using System.Collections; 
using System.IO; 
using System.Runtime.Remoting; 
using System.Runtime.Remoting.Messaging; 
using System.Runtime.Remoting.Channels; 
using System.Threading; 
using System.Net; 

namespace MyRemotingEnvironment 
{ 
    public class ClientIPServerSinkProvider : 
     IServerChannelSinkProvider 
    { 
     private IServerChannelSinkProvider _nextProvider = null; 

     public ClientIPServerSinkProvider() 
     { 
     } 

     public ClientIPServerSinkProvider(
      IDictionary properties, 
      ICollection providerData) 
     { 
     } 

     public IServerChannelSinkProvider Next 
     { 
      get { return _nextProvider; } 
      set { _nextProvider = value; } 
     } 

     public IServerChannelSink CreateSink(IChannelReceiver channel) 
     { 
      IServerChannelSink nextSink = null; 

      if (_nextProvider != null) 
      { 
       nextSink = _nextProvider.CreateSink(channel); 
      } 
      return new ClientIPServerSink(nextSink); 
     } 

     public void GetChannelData(IChannelDataStore channelData) 
     { 
     } 
    } 



    public class ClientIPServerSink : 
     BaseChannelObjectWithProperties, 
     IServerChannelSink, 
     IChannelSinkBase 
    { 

     private IServerChannelSink _nextSink; 

     public ClientIPServerSink(IServerChannelSink next) 
     { 
      _nextSink = next; 
     } 

     public IServerChannelSink NextChannelSink 
     { 
      get { return _nextSink; } 
      set { _nextSink = value; } 
     } 

     public void AsyncProcessResponse(
      IServerResponseChannelSinkStack sinkStack, 
      Object state, 
      IMessage message, 
      ITransportHeaders headers, 
      Stream stream) 
     { 
      IPAddress ip = headers[CommonTransportKeys.IPAddress] as IPAddress; 
      CallContext.SetData("ClientIPAddress", ip); 
      sinkStack.AsyncProcessResponse(message, headers, stream); 
     } 

     public Stream GetResponseStream(
      IServerResponseChannelSinkStack sinkStack, 
      Object state, 
      IMessage message, 
      ITransportHeaders headers) 
     { 

      return null; 

     } 


     public ServerProcessing ProcessMessage(
      IServerChannelSinkStack sinkStack, 
      IMessage requestMsg, 
      ITransportHeaders requestHeaders, 
      Stream requestStream, 
      out IMessage responseMsg, 
      out ITransportHeaders responseHeaders, 
      out Stream responseStream) 
     { 
      if (_nextSink != null) 
      { 
       IPAddress ip = 
        requestHeaders[CommonTransportKeys.IPAddress] as IPAddress; 
       CallContext.SetData("ClientIPAddress", ip); 
       ServerProcessing spres = _nextSink.ProcessMessage(
        sinkStack, 
        requestMsg, 
        requestHeaders, 
        requestStream, 
        out responseMsg, 
        out responseHeaders, 
        out responseStream); 
       return spres; 
      } 
      else 
      { 
       responseMsg = null; 
       responseHeaders = null; 
       responseStream = null; 
       return new ServerProcessing(); 
      } 
     } 


    } 
} 

तब जब आप अपने दूरस्थ होस्ट शुरू की तरह निम्नलिखित कुछ करना:

BinaryServerFormatterSinkProvider bp = new BinaryServerFormatterSinkProvider(); 
ClientIPServerSinkProvider csp = new ClientIPServerSinkProvider(); 
csp.Next = bp; 
Hashtable ht = new Hashtable(); 
ht.Add("port", "1234"); // Your remoting port number 
TcpChannel channel = new TcpChannel(ht, null, csp); 
ChannelServices.RegisterChannel(channel, false); 

RemotingConfiguration.RegisterWellKnownServiceType(
    typeof(MyRemotedClass), 
    "MyRemotedClass.rem", 
    WellKnownObjectMode.SingleCall); 

अपने विधि में आप कॉल ग्राहक द्वारा आईपी पते तक पहुंच सकते हैं:

public class MyRemotedClass : MarshalByref 
{ 
    public void DoThis() 
    { 
     string clientIP = CallContext.GetData("ClientIPAddress").ToString(); 
    } 
} 
+4

क्या यह वास्तव में क्लाइंट आईपी पता प्राप्त करने के लिए यह जटिल है? – IAbstract

+2

@ डबर्मन - यह एकमात्र तरीका है। लेकिन अगर आप अपने स्वयं के चैनल सिंक कक्षाओं को लिखने के लिए उपयोग कर चुके हैं तो यह जीवन को रिमोट करने का एक सामान्य हिस्सा बन जाता है। – Kev

+0

हाँ, दुर्भाग्य से मेरे लिए यह वास्तव में Remoting में मेरा पहला प्रयास है ... जिसे मैं अभी के लिए अलग कर रहा हूं। मैं रीमोटिंग का उपयोग करने के लिए उत्सुक नहीं हूं जब मैं मार्क ग्रेवेल के प्रोटोबफ-नेट को कार्यान्वित कर सकता हूं :) मैं अब के लिए थोड़ा अलग दिशा में जा रहा हूं ... आपकी मदद के लिए धन्यवाद, थू। – IAbstract

संबंधित मुद्दे