ast*_*ich 5 .net c# .net-remoting
我正在尝试构建一个非常简单的 .Net 远程连接,但似乎无法弄清楚神奇的咒语。
我有一个服务器端类,它是一个单例,并且在服务过程期间处于活动状态。
public class MyRemoteServerClass : MarshalByRefObject
{
public void DoSomething()
{
System.Diagnostics.Trace.Assert(false);
}
public override object InitializeLifetimeService()
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
根据我对 .Net 远程处理的阅读,我编写了以下代码来实例化并在服务中注册服务器类:
static void Main(string[] args)
{
MyRemoteServerClass server = new MyRemoteServerClass();
TcpChannel channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel, false);
string url = "tcp://localhost:8080/MyRemoteServerClass";
RemotingServices.Marshal(server, url, server.GetType());
System.Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
我在 .Net winforms 客户端中编写了以下代码来调用“MyRemoteServerClass.DoSomething”函数:
private void button1_Click(object sender, EventArgs e)
{
string url = "tcp://localhost:8080/MyRemoteServerClass";
ChannelServices.RegisterChannel(new TcpChannel(), false);
MyRemoteServerClass root = Activator.GetObject(typeof(MyRemoteServerClass), url) as MyRemoteServerClass;
root.DoSomething();
}
Run Code Online (Sandbox Code Playgroud)
“Activate.GetObject”调用似乎获取对服务器“MyRemoteServerClass”实例的代理引用。但是,当我调用“DoSomething”时,我收到“未找到请求的服务”异常。
{System.Runtime.Remoting.RemotingException:找不到请求的服务
服务器堆栈跟踪:位于 System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage&responseMsg, ITransportHeaders&responseHeaders, Stream&responseStream)
在 [0] 重新抛出异常:在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 在 RemoteExampleServer.MyRemoteServerClass。 DoSomething() at RemoteExampleClient.Form1.button1_Click(Object sender, EventArgs e) in c:\Aaron\RemoteExampleClient\Form1.cs:line 30} System.Exception {System.Runtime.Remoting.RemotingException}
我究竟做错了什么?请注意,我已允许通过防火墙访问这些应用程序(当我完全禁用防火墙时,我会得到相同的行为)。我的计算机上没有其他安全软件。
谢谢,
亚伦
附言。我更喜欢不涉及修改“App.config”xml 的解决方案。如果可能的话,我希望在代码空间中配置 .Net 远程连接。
问题是,在服务器端,您将对象的 URI 指定为其完整 URL。在这种情况下,URI 只是"MyRemoteServerClass". 因此,要修复它,请将服务器 main 方法更改为:
static void Main(string[] args)
{
MyRemoteServerClass server = new MyRemoteServerClass();
TcpChannel channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel, false);
string uri = "MyRemoteServerClass";
RemotingServices.Marshal(server, uri, server.GetType());
System.Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
请注意,在客户端,您将在按钮单击处理程序中注册通道。这只会起作用一次;第二次单击该按钮时,您将收到异常,RegisterChannel因为通道“tcp”已注册。要解决此问题,您可以通过一次调用替换这两行RemotingServices.Connect,这将根据需要创建通道:
private void button1_Click(object sender, EventArgs e)
{
string url = "tcp://localhost:8080/MyRemoteServerClass";
MyRemoteServerClass root = RemotingServices.Connect(typeof(MyRemoteServerClass),
url) as MyRemoteServerClass;
root.DoSomething();
}
Run Code Online (Sandbox Code Playgroud)