鉴于此MarshalByRef类:
public class MyRemotedClass : MarshalByRef
{
public void DoThis()
{
...
}
public void DoThat()
{
...
}
}
客户端代码:
MyRemotedClass m = GetSomehowMyRemotedClass();
m.DoThis();
m.DoThat();
我可以让几个客户同时做同样的事情。 我想区分客户。 如何在远程访问的方法中识别执行远程调用的人员? 例如,我可以记录谁做了什么。 (实际上,我不需要追溯真正的客户信息,我只是希望能够对客户进行分组调度。)
[已编辑添加更多背景信息]
我需要处理大量代码,包括属性。因此,不能选择扩展输入参数列表。
答案 0 :(得分:16)
您可以做的一件事是通过实施IServerChannelSinkProvider
按IP地址识别客户。
将此类添加到远程主机项目中:
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();
}
}