【问题标题】:Retrieve IMessage target instance from IServerChannelSink从 IServerChannelSink 检索 IMessage 目标实例
【发布时间】:2020-04-14 18:19:45
【问题描述】:

在两个进程之间使用 .NET 远程处理,我在服务器端插入我自己的 IServerChannel 接收器,这样我就可以拦截客户端启动的方法调用并将它们移动到服务器上的适当线程。我目前正在努力将消息的Uri 转换为服务器对象实例,以便我可以检查它:

public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
                                      IMessage requestMsg,
                                      ITransportHeaders requestHeaders,
                                      Stream requestStream,
                                      out IMessage responseMsg,
                                      out ITransportHeaders responseHeaders,
                                      out Stream responseStream)
{
  if (requestMsg is MethodCall methodCallMessage)
  {
    // how do I implement ConvertUriToObjectInstance to convert the Uri to a MarshallByRef instance???
    object instance = ConvertUriToObjectInstance(requestMsg.Uri);
  }
}

有没有办法将 Uri 转换为服务器创建的对象到实际的 MarshallByRef 实例?

我已经通过文档和参考源查看了System.Runtime.Remoting.Messaging 命名空间/类,但我看不到任何与将 Uri 转换回它所代表的实际实例相关的内容。运行时显然有办法做到这一点,但有没有办法我可以通过官方 api 或利用反射来获得它?

注意我知道我可以通过ContextBoundObject 之类的方式转换线程,但由于它的限制,我会避免使用它——比如 w.r.t.泛型。

【问题讨论】:

  • 您不应该转换响应(而不是请求)吗?
  • 否;当客户端调用“MyMethodThatShouldRunOnTheUiThreadOnTheServer”时,我想将方法​​调用转换到 UI 线程。

标签: c# .net remoting


【解决方案1】:

查看the implementation of ChannelServices.DispatchMessage,它看起来像调用CheckDisconnectedOrCreateWellKnownObject,它返回一个ServerIdentity 对象,其中包含一个TPOrObject 属性,似乎解析为MarshalByRef 实例。

因此,可以使用以下反射代码从消息中检索实例(省略错误检查):

private static MethodInfo CheckDisconnectedOrCreateWellKnownObject
  = typeof(ChannelServices).GetMethod(nameof(CheckDisconnectedOrCreateWellKnownObject), BindingFlags.Static | BindingFlags.NonPublic);

private static MethodInfo InstanceProperty
  = Type.GetType("System.Runtime.Remoting.Identity", true)
        .GetProperty("TPOrObject", BindingFlags.NonPublic | BindingFlags.Instance)
        .GetGetMethod(nonPublic: true);

private static object GetObjectInstance(IMessage methodCallMessage)
{
  var wellKnownObject = CheckDisconnectedOrCreateWellKnownObject.Invoke(null, new object[] { methodCallMessage });
  return InstanceProperty.Invoke(wellKnownObject, null);
}

但不能保证这是否总是正确的。

【讨论】:

    猜你喜欢
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多