我们在使用.NET Remoting时遇到了一个奇怪的问题.基本上,我们有一个服务器,它注册两个TcpChannels ChannelServices.RegisterChannel():
然后我们有一个客户端注册一个TcpChannel,以便能够与服务器通信.我们通过Activator.GetObject()使用URI 调用从服务器检索一个对象
"TCP:// SERVERIP:50000 /对象名"
这工作正常,客户端连接到端口50000上的服务器并获取对象.
但是,当我们开始调用该对象上的方法时,将丢弃与端口50000上的通道的连接,并自动在端口15000上建立与该通道的新连接.这对我们来说是一个真正的问题,因为我们不希望端口15000上的流量,因为该通道可能没有绑定到与服务器上的端口50000通道相同的网络适配器,或者该端口可能未在防火墙中打开,这会导致远程召唤自然失败.
这对我们来说非常奇怪,因为客户端在我们的代码中不知道端口15000上的服务器上存在另一个通道或它侦听的IP,但它尝试连接到它.
非常感谢任何帮助,
谢谢,卡斯帕
这是设置其中一个服务器通道的代码,通常在端口50000上:
IDictionary props = new Hashtable();
props["port"] = m_tcpPort;
props["name"] = String.Empty;
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
m_tcpChannel = new TcpServerChannel( props, /*clientProvider,*/ serverProvider );
ChannelServices.RegisterChannel( m_tcpChannel, false );
m_wellKnownObjRef = RemotingServices.Marshal( this, "Server@" + m_tcpPort.ToString() );
Run Code Online (Sandbox Code Playgroud)
这是设置其他服务器通道的代码,通常在端口15000上:
IDictionary props = new Hashtable();
props["name"] = String.Empty;
props["port"] = ip.Port;
props["bindTo"] = ip.Address.ToString();
props["timeout"] = …Run Code Online (Sandbox Code Playgroud) 我一直在尝试使用以下代码(所有内容都在同一个程序集中定义):
namespace SomeApp{
public class A : MarshalByRefObject
{
public byte[] GetSomeData() { // }
}
public class B : MarshalByRefObject
{
private A remoteObj;
public void SetA(A remoteObj)
{
this.remoteObj = remoteObj;
}
}
public class C
{
A someA = new A();
public void Init()
{
AppDomain domain = AppDomain.CreateDomain("ChildDomain");
string currentAssemblyPath = Assembly.GetExecutingAssembly().Location;
B remoteB = domain.domain.CreateInstanceFromAndUnwrap(currentAssemblyPath,"SomeApp.B") as B;
remoteB.SetA(someA); // this throws an ArgumentException "Object type cannot be converted to target type."
}
}
}
Run Code Online (Sandbox Code Playgroud)
我要做的是将第一个AppDomain中创建的"A"实例的引用传递给子域,并让子域在第一个域上执行方法.在'B'代码的某些方面,我将调用'remoteObj.GetSomeData()'.必须这样做,因为'GetSomeData'方法中的'byte …
我有一个分布式应用程序,它在内部千兆网络上使用.NET Remoting.有一台服务器,以及十几个连接到服务器的客户端.客户端运行多个线程,每个客户端最多可以有10个并发请求.
这个应用程序大多数时候都很好用.服务器一次保持数月.我不时会在客户端上遇到异常,我无法弄清楚导致异常的原因.异常和堆栈跟踪是:
System.Runtime.Remoting.RemotingException: Tcp channel protocol violation: expecting preamble.
Server stack trace:
at System.Runtime.Remoting.Channels.Tcp.TcpSocketHandler.ReadAndMatchPreamble()
at System.Runtime.Remoting.Channels.Tcp.TcpSocketHandler.ReadVersionAndOperation(UInt16& operation)
at System.Runtime.Remoting.Channels.Tcp.TcpClientSocketHandler.ReadHeaders()
at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream)
at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪回到我进行远程调用的地方.
我看起来并且在我正在进行的调用中或在服务器返回的数据中找不到任何异常.
谷歌搜索此错误并不是很有成效.我见过的大多数错误都是围绕某人从HTTP转换为TCP而不是改变所有内容,所以当他们尝试连接时会遇到异常.在我的情况下,客户端将在我收到此错误之前运行几天.
另一个数据点:服务器确实收到了很多请求.大多数客户端都是Web爬虫,每个客户端每分钟向服务器发出2,000多个请求.因此,服务器每秒处理超过500个请求,具有更高流量的突发.在任何情况下,服务器似乎处理流量没问题,如果服务器过载,我会发现一个非常不同的错误.
是什么原因造成了这个错误?
我正在编写.NET Remoting应用程序.我的dll,服务器和客户端都正常工作.但是,当我尝试更改我的方法调用以获取对象参数而不是像int这样的简单类型时,它会抱怨此错误.
键入System.Runtime.Remoting.ObjRef及其中的类型(例如System.Runtime.Remoting.ObjRef)不允许在此安全级别进行反序列化.
方法是这样的.
public List<Orders> GetOrders(int UserID) { //Works
public List<Orders> GetOrders(Users user) { // Doesnt Work
[Serializable]
public class Users : MarshalByRefObject {
Run Code Online (Sandbox Code Playgroud)
现在我已经创建了User类,[Serializable]并给它MarshalByRefObject继承.这可能是我的问题吗?我试过从User类中删除[Serializable]并且它抱怨因为它无法解释它.
编辑 好的,这是我的客户端方法.
IChannel channel = new TcpClientChannel();
ChannelServices.RegisterChannel(channel, false);
CustomType Server = (CustomType)Activator.GetObject(typeof(CustomType), "tcp://localhost:9934/CustomType");
Run Code Online (Sandbox Code Playgroud)
这是我的服务器.
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = 9934;
TcpChannel channel = new TcpChannel(props, null, provider);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(CustomType), "CustomType", WellKnownObjectMode.Singleton);
Console.WriteLine("Server is initialized");
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud) 我正在开发一个需要AppDomain进程间进程和进程间进程内部通信的项目.是的......我知道...... NET Remoting被广泛认为是一种传统技术,但我面临两个非常特殊的问题,也许在这些情况下,WCF并不是NET Remoting的完全替代品.
1)app -main进程间进程内通信
我正在开始的应用程序启动,需要搜索并加载一个更多的插件.我希望在单独的AppDomain中加载每个插件.我需要一种方法在他的AppDomain中创建每个Addin实例,并在某个时刻调用此实例的一些接口方法.NET Remoting是唯一的方法,对吧?此外,如果我们希望应用System.Addins范例,显然只基于NET Remoting并且没有标记为过时...
2)进程间 - 机器内通信
在这里,我可以肯定地从我的应用程序中公开WCF服务,并使用命名管道从我的客户端调用此服务.
我真正想做的是从我的应用程序中公开一个对象模型,这样我的应用程序就可以从一些.NET客户端自动化,就像Excel公开的OLE/COM Automation对象模型一样.任何COM客户端都可以获得对Excel.Application的对象引用,并查询打开的文档,打开一些新文档等等.
我认为WCF以独立于平台的方式进行通信是很好的.但在这种情况下,我只需要在同一台机器上从Net客户端与Net应用程序进行通信.我认为,WCF服务哲学不允许使用对象,集合,字段,静态成员,方法重载来公开富对象模型......或者我错了?
请原谅我的坏英语和我的新手问题.
Windows无法使32位进程加载64位dll,因此我尝试使用远程处理以允许32位进程与64位进程交互.
这就是问题所在:虽然两个应用程序位于同一台机器上,但一个是32位,另一个是64位,它们必须是这样的:32位或64位都会破坏这些应用程序构建在顶层的所有内容的.
我正在使用.NET的System.Runtime.Remoting.RemotingConfiguration类并调用其Configure()方法并将引用传递给App.config文件,该文件引用我将通过远程处理访问的MarshalByRefObject类.
我得到它的工作,但只有长,Client,Host,MarshalByRefObject类是32位或64位.如果我把它们混合起来这将无效:我最终会遇到BadImageFormatException:
无法加载文件或程序集"MyRemotingObject"或其依赖项之一.尝试加载格式不正确的程序.
只要我将这两个应用程序设置为32位或64位,异常就会消失,但同样,其中一个必须是32位,另一个必须是64位.
有人能告诉我如何在32位.NET应用程序和.64位.NET应用程序之间启用进程间通信吗?
假设我有一个通用接口 IService<T>和一个实现它的类Service : IService<Bar>
我创建了该接口的代理:
var proxy = new DynamicProxy<IService<Bar>>(new Service()).GetTransparentProxy() as IService<Bar>;
Run Code Online (Sandbox Code Playgroud)
DynamicProxy是RealProxy的一个简单实现:
public class DynamicProxy<I> : RealProxy
{
private I _decorated;
public DynamicProxy(I decorated) : base(typeof(I))
{
this._decorated = decorated;
}
public override IMessage Invoke(IMessage msg)
{
IMethodCallMessage methodCall = (IMethodCallMessage)msg;
MethodInfo methodInfo = methodCall.MethodBase as MethodInfo;
return new ReturnMessage(
methodInfo.Invoke(this._decorated, methodCall.InArgs),
null,
0,
methodCall.LogicalCallContext,
methodCall);
}
}
Run Code Online (Sandbox Code Playgroud)
直接使用我的代理时它工作正常:
IEnumerable<Bar> bars = new List<Bar>() { new Bar { id = 2 }, new Bar { id …Run Code Online (Sandbox Code Playgroud) 你好,
我们拥有数百台虚拟机的大型环境.在我们的服务部署期间,我们需要将一些文件从build drop复制到所有这些机器.
所以,我们有:
Powershell用作脚本语言.就像是:
$buildDrop = "\\sourceMachine\Build"
$machineTarget = "targetMachine"
Invoke-Command -ComputerName $machineTarget -ArgumentList $buildDrop -ScriptBlock {
Param( $buildDrop )
Test-Path $buildDrop # Will return False
}
Run Code Online (Sandbox Code Playgroud)
这种方法导致双跳问题,由于在XP和2k3机器上不支持CredSSP功能,我无法解决这个问题.在用户计算机上调用的副本会导致性能瓶颈(数据通过用户计算机传输).
是否有任何方法可以使所有目标机器始终显示构建丢弃?可能以某种方式将它们添加到受信任的位置或类似的东西?
提前致谢!
我无法从本地计算机访问Powershell远程会话中的服务器上的UNC路径.我可以直接在Servers Cmd提示符中使用它们.
实际上,我已登录到服务器并将UNC路径映射为本地驱动器(例如X :).使用登录时重新连接选项.
我有一个批处理文件驻留在这个X:驱动器中,我想使用本地脚本中的invoke命令远程运行它.但是,它失败了.
它说"找不到驱动器.名称为X的驱动器不存在".
此外,当我尝试使用scriptblock中的net use命令映射驱动器时,它也会抛出错误 - 系统错误1223 - 本机命令错误.
我使用管理员凭据登录此服务器.
任何人都可以请帮助我,我想要做的就是远程运行脚本驻留在这个UNC路径?
此外,当我将服务器中的UNC路径映射为本地驱动器时,为什么我无法在PS远程会话中使用它?
提前致谢.TS
remoting ×10
.net ×6
c# ×5
powershell ×2
32-bit ×1
64-bit ×1
add-in ×1
appdomain ×1
channels ×1
generics ×1
invoke ×1
ipc ×1
mapping ×1
proxy ×1
reflection ×1
serializable ×1
wcf ×1
windows ×1
windows-xp ×1