我正在使用.NET远程处理从Windows服务检索定期状态更新到"控制器"应用程序,该应用程序用于显示有关服务正在执行的操作的一些实时统计信息.
由此产生的网络流量巨大 - 是更新数据大小的很多倍 - 所以很明显我以非常低效的方式错误地实现了远程代码.作为修复它的第一步,我需要监控服务用于与控制器通信的IP端口上的流量,以便我可以建立基线然后验证修复.
任何人都可以推荐一种实用程序和/或编码技术,我可以使用它来获取流量统计数据吗?端口的"字节发送"计数就足够了.
简单来说,我编写了一个JSE Swing应用程序,需要与我之前编写的GWT服务器通信.我非常喜欢GWT在它的javascript和服务器端之间进行远程处理的方式,并希望我可以利用这种机制.有没有人设法以这种方式使用GWT-RPC?我应该去Restlet吗?
我有一些.NET远程代码,其中一个工厂方法,在一些服务器端类中实现,返回到具体对象的接口,也在同一台服务器上执行..NET远程处理自动创建代理,并允许我将接口传递给客户端,然后客户端可以直接调用它们.
示例接口:
public interface IFactory
{
IFoo GetFoo();
}
public interface IFoo
{
void DoSomething();
}
Run Code Online (Sandbox Code Playgroud)
示例客户端代码:
...
IFactory factory = (IFactory) System.Activator.GetObject (typeof (IFactory), url);
...
IFoo foo = factory.GetFoo (); // the server returns an interface; we get a proxy to it
foo.DoSomething ();
...
Run Code Online (Sandbox Code Playgroud)
一切都很好.但是,现在我正在尝试将我的代码迁移到WCF.我想知道是否有一种方法来传递接口并让WCF在客户端上动态生成代理,就像原始的.NET远程处理一样.
而且我不想返回类实例,因为我不想暴露真正的类.并且序列化完整实例并在服务器和客户端之间来回发送也不是一种选择.我真的只是希望客户端通过接口指针/代理与服务器对象通信.
有任何想法吗?
我正在研究一种客户端 - 服务器解决方案,它使用.NET 2.0 Remoting(服务器激活,TCP通道上的二进制格式化,Vista Ultimate)进行通信.目前我正在分析应用程序并在同一台机器上运行所有内容.我注意到,如果我启动应用程序,一切都运行良好几分钟,然后突然每个远程调用需要几秒钟才能执行.我已经记录了两端并为每个呼叫计时.服务器端的实现只需要几分之一秒的时间来执行,而整个远程调用很慢.进一步的分析表明远程服务在服务器端降级:当远程服务的内部工作在几分之一秒内执行时,响应非常慢.如果我重新启动服务器,一切都会恢复正常几分钟.
有没有人经历过这样的事情?
谢谢!
更新:我检查过,如果我将远程对象的生命周期配置为1天,我仍然遇到同样的问题.
更新:我正在使用Ingo Ramer建议的模式(HOWTO:使用基于接口的远程对象和配置文件)来处理所有远程处理的东西,如果这有任何区别的话.
客户代码:
public static object CreateInstance(Type type)
{
if (!Initialized)
InitWellKnownTypesCache();
WellKnownClientTypeEntry typeEntry = (WellKnownClientTypeEntry)wellKnownTypesCache[type];
if (null == typeEntry)
throw new RemotingException("Type not found.");
if (string.IsNullOrEmpty(serverObjectActivationUri))
throw new RemotingException("ServerObjectActivationUri wasn't configured. Cannot create server object instance.");
return Activator.GetObject(typeEntry.ObjectType, string.Format(serverObjectActivationUri, typeEntry.ObjectUrl));
}
Run Code Online (Sandbox Code Playgroud)
服务器端只有正确的配置文件,如下所示:
<service>
<wellknown
mode="Singleton"
type="MyDomain.SomeDomain, MyDomain"
objectUri="SomeDomainService"
/>
Run Code Online (Sandbox Code Playgroud)
除了RemotingConfiguration.Configure("MyDomainService.exe.config",false)之外我什么都不做; 我的服务器和客户端代码都没有.
有没有人有任何链接到一个好的,简洁的,教程或.Net远程指南?将感激不尽!
谢谢(对不起,短信!)
编辑:我现在知道:http://www.codeproject.com/KB/XML/remotingsimpleeng.aspx
我遇到了一个远程异常:
"此远程处理代理没有通道接收器,这意味着服务器没有正在侦听的注册服务器通道,或者此应用程序没有合适的客户端通道与服务器通信."
我找到的博客文章最好地解释了原因:
第二种情况更加模糊.这发生在客户端调用服务器,服务器返回对象引用,然后客户端对服务器上引用的对象进行调用的情况.如果引用的对象位于服务器上的辅助AppDomain中,则可能抛出上述异常.如果出现问题,那是因为频道注册仅适用于调用RegisterChannel且未在辅助AppDomain中注册的频道的AppDomain.返回到客户端的对象引用指向辅助AppDomain中的对象,而不是指向主AppDomain中的代理,因此客户端和辅助AppDomain之间没有通道,调用可以通过该通道.解决方案:在引用对象所在的辅助AppDomain中注册通道.
这确实适合我的场景,因为我有一个服务将插件加载到单独的appdomains中.对象实例(在所有程序集引用的程序集中定义的接口的实现)在辅助应用程序域中创建并由服务引用(跨应用程序域,因此服务具有代理引用).然后,该服务将这些代理引用返回给应用程序.应用程序和服务之间存在已注册的通道,但插件和应用程序之间没有任何通道.
我认为代理就足以跨越appdomain边界.我真的必须在插件和应用程序之间创建通道吗?这似乎不对,所以我必须遗漏一些东西.
我昨晚遇到了两个问题,我现在已经解决了,但我不能100%确定为什么我所做的已经解决了这些问题,希望也许有人可以提供一些见解,因为我已经翻了很多岩石,没有运气!
第一个问题
第一个问题是我在两个独立的程序中有两个唯一命名的管道:
但是,由于已经在使用的地址,第二个启动的程序在打开ServiceHost时会抛出一个异常(我相信它是AddressAlreadyInUseException).
我的方式是实例化这些ServiceHosts如下:
Uri[] baseAddresses = new Uri[] { new Uri("net.pipe://localhost") };
this.host = new ServiceHost(this, baseAddresses);
this.host.AddServiceEndpoint(typeof(IHostType), new NetNamedPipeBinding(), "superuniquepipe1");
this.host.Open();
Run Code Online (Sandbox Code Playgroud)
所以我首先指定localhost的基地址,然后在添加端点时指定其余部分,我解决这个问题的方法是更改代码,如下所示:
this.host = new ServiceHost(this);
this.host.AddServiceEndpoint(typeof(IHostType), new NetNamedPipeBinding(), "net.pipe://localhost/superuniquepipe2");
this.host.Open();
Run Code Online (Sandbox Code Playgroud)
我是否正确说这个有效的原因是因为它只检查基地址而不是我试图添加的端点?并使用第二个代码示例一个有效/安全的方式让多个程序监听"localhost"?
第二个问题:
为了解决上述问题,我将基本地址从localhost更改为许多不同的唯一字符串,例如"net.pipe:// rawrwhyisntthisworkingsadface",但是在执行此操作时,我将从客户端尝试使用InvalidCredentialException建立连接(见下面的代码)
我的印象是命名管道可以命名为任何东西,任何人都可以对这一个有所了解吗?
ChannelFactory<IHostType> factory = new ChannelFactory<IHostType>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://rawrwhyisntthisworkingsadface/superuniquepipe2"));
IHostType proxy = factory.CreateChannel();
proxy.CallSomeMethodAndGetAnException();
Run Code Online (Sandbox Code Playgroud)
任何输入都会非常感激,因为我说我已经解决了这个问题并且只是想知道为什么我的解决方案有效,但是如果你看到我如何解决它的一个缺陷并且可以提出一个更好的方法,请这样做:)
我正在使用Logical CallContext在一系列等待中回传信息.有趣的是,在我的测试控制台应用程序中,一切正常.但是,当在VS UnitTest的上下文中运行我的单元测试时,调用上下文似乎没有流过等待.
方法内部:SendRequestAsyncImpl正在设置调用上下文,当我在方法返回时从断点查询逻辑调用上下文时,调用上下文设置得很好.
但是,在await返回以下行之后:
Message response = await SendRequestAsyncImpl(m, true).ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
逻辑调用上下文为空.我想也许可以通过设置ConfigureAwait(true)而不是false来解决问题.但这并不能解决问题.
无论我尝试流动什么,甚至在SendRequestAsyncImpl中设置一个简单的值类型,如:
System.Runtime.Remoting.Messaging.CallContext.LogicalSetData("flag", true);
Run Code Online (Sandbox Code Playgroud)
await后无法检索.
为什么这可以从我的控制台应用程序工作 但不是从我的单元测试?有什么不同?(我已经看到了其他一些涉及AppDomain问题的堆栈溢出问题.但是我甚至无法在整个等待期间编组一个bool.编组数据的能力似乎不是问题.)
我们有一个基于.NET Remoting的传统应用程序.我们的客户端客户端库目前仅支持同步操作.我想用基于TPL的async Task<>方法添加异步操作.
作为概念证明,我已经基于这些指令的修改版本设置了基本的远程服务器/客户端解决方案.
我还发现这篇文章描述了如何将基于APM的异步操作转换为基于TPL的异步任务(使用Task.Factory.FromAsync)
我不确定的是我是否被迫在其中指定回调函数.BeginInvoke()并且还指定了.EndInvoke().如果两者都是必需的,回调函数与之间的区别究竟是什么.EndInvoke().如果只需要一个,我应该使用哪一个来返回值,并确保我没有内存泄漏.
这是我当前的代码,我没有将回调传递给.BeginInvoke():
public class Client : MarshalByRefObject
{
private IServiceClass service;
public delegate double TimeConsumingCallDelegate();
public void Configure()
{
RemotingConfiguration.Configure("client.exe.config", false);
var wellKnownClientTypeEntry = RemotingConfiguration.GetRegisteredWellKnownClientTypes()
.Single(wct => wct.ObjectType.Equals(typeof(IServiceClass)));
this.service = Activator.GetObject(typeof(IServiceClass), wellKnownClientTypeEntry.ObjectUrl) as IServiceClass;
}
public async Task<double> RemoteTimeConsumingRemoteCall()
{
var timeConsumingCallDelegate = new TimeConsumingCallDelegate(service.TimeConsumingRemoteCall);
return await Task.Factory.FromAsync
(
timeConsumingCallDelegate.BeginInvoke(null, null),
timeConsumingCallDelegate.EndInvoke
);
}
public async Task …Run Code Online (Sandbox Code Playgroud) remoting ×10
.net ×5
c# ×3
wcf ×2
appdomain ×1
async-await ×1
gwt ×1
java ×1
named-pipes ×1
networking ×1
restlet ×1
return ×1
silverlight ×1
swing ×1
windows ×1