【发布时间】:2015-03-05 10:24:37
【问题描述】:
我有一个MarshalByReferenceObject,它的方法通过 .net 远程调用。
public class MyServer : MarshalByReferenceObject
{
public void DoSomething();
}
System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownServiceType(
typeof(MyServer), "serverUrl", System.Runtime.Remoting.WellKnownObjectMode.SingleCall);
客户端像这样调用服务器:
var server = Activator.GetObject(typeof(MyServer), "serverUrl");
server.DoSomething();
现在出于调试目的,当客户端调用 DoSomething() 方法时,我想记录实际调用者是谁。
如何从我的 server.DoSomething() 函数中识别调用方法?或者从我的服务器构造函数中,它由 Activator.GetObject 调用?
理想情况下,我想要整个堆栈跟踪:哪个客户端方法调用服务器,哪个父方法调用该客户端方法,等等。但我会满足于一些类型的来电显示。我控制着客户,所以也许我可以以某种方式给他们起名字?接口规范已经非常固定,因此我希望避免为每个方法添加一个多余的 string callerId 参数。
本地堆栈跟踪当然只识别System.Runtime.Remoting 方法,而不是实际的远程调用者。
服务器端的示例堆栈跟踪:
at MyServer.MyServer(), line 123
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
[...]
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
这显然不能帮助我从客户端识别调用方法。
【问题讨论】:
-
如果你控制双方,为什么不将这些信息作为参数添加?
-
我控制双方,但调用的方法签名是由接口规范预先确定的,我宁愿不改变。它有很多方法,从很多地方调用。
-
这会排除像重载 ctor 这样的东西吗?
-
@Plutonix 不,构造函数可以重载,因为它实际上并未包含在规范中。但是Activator.GetInstance 方法不允许我将任何参数传递给构造函数。我唯一能传递的是某种“通道状态”对象,它只在内部使用。似乎无法使用自定义构造函数创建服务器对象。
-
@HugoRune - 我在远程处理方面做得不多,但我做了一些快速的研究......你能实现 IServerChannelSinkProvider 并以某种方式利用那里的信息来获得你需要的关于客户...msdn.microsoft.com/en-us/library/…
标签: c# stack-trace remoting marshalbyrefobject