Identifying the client during a .NET remoting invocation

前端 未结 1 492

Given this MarshalByRef class:

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


        
相关标签:
1条回答
  • 2020-11-30 08:55

    One of the things you can do is identify a client by IP address by implementing an IServerChannelSinkProvider.

    Add this class to your remoting host project:

    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();
                }
            }
    
    
        }
    }
    

    Then when you start your remoting host do something like the following:

    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);
    

    In your method calls you can access the IP address of the client by doing:

    public class MyRemotedClass : MarshalByref
    {
        public void DoThis()
        {
            string clientIP = CallContext.GetData("ClientIPAddress").ToString();
        }
    }
    
    0 讨论(0)
提交回复
热议问题