鉴于此MarshalByRef类:
public class MyRemotedClass : MarshalByRef { public void DoThis() { ... } public void DoThat() { ... } }
客户端代码:
MyRemotedClass m = GetSomehowMyRemotedClass(); m.DoThis(); m.DoThat();
我可以让几个客户同时做同样的事情.我想区分客户.如何在远程访问的方法中识别执行远程调用的人员? 例如,我可以记录谁做了什么.(实际上,我不需要追溯真正的客户信息,我只是希望能够对客户进行分组调用.)
[已编辑添加更多背景信息]
我有大量的代码需要覆盖,包括属性.因此,不能选择扩展输入参数列表.
您可以做的一件事是通过实现一个IP地址来识别客户端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);
在方法调用中,您可以通过执行以下操作来访问客户端的IP地址:
public class MyRemotedClass : MarshalByref { public void DoThis() { string clientIP = CallContext.GetData("ClientIPAddress").ToString(); } }