在.NET远程处理RemotingConfiguration.RegisterWellKnownServiceType和RemotingServices.Marshal之间有什么区别?
我想要做的是在Windows服务中创建一个对象,然后将其作为远程处理对象放入,并使Windows服务和客户端都作用于远程处理对象.
我认为下面的代码可以实现这一点.
FooRemoting foo = new FooRemoting();
RemotingConfiguration.RegisterWellKnownServiceType(typeof(FooRemoting), serverName, WellKnownObjectMode.Singleton);
RemotingServices.Marshal(foo);
Run Code Online (Sandbox Code Playgroud) 我想在AppDomains中使用一个对象.
为此,我可以使用[Serializeable]属性:
[Serializable]
class MyClass
{
public string GetSomeString() { return "someString" }
}
Run Code Online (Sandbox Code Playgroud)
或MarshalByRefObject的子类:
class MyClass: MarshalByRefObject
{
public string GetSomeString() { return "someString" }
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我都可以使用这样的类:
AppDomain appDomain = AppDomain.CreateDomain("AppDomain");
MyClass myObject = (MyClass)appDomain.CreateInstanceAndUnwrap(
typeof(MyClass).Assembly.FullName,
typeof(MyClass).FullName);
Console.WriteLine(myObject.GetSomeString());
Run Code Online (Sandbox Code Playgroud)
为什么两种方法似乎都有相同的效果?两种方法有什么不同?我什么时候应该支持另一种方法呢?
编辑:从表面上看,我知道两种机制之间存在差异,但如果有人跳出丛林并问我这个问题,我无法给他一个正确的答案.问题是非常开放的问题.我希望有人可以比我能做的更好地解释它.
我有战争依赖:
<dependency>
<groupId>my.package</groupId>
<artifactId>myservices</artifactId>
<version>0.3</version>
<type>war</type>
</dependency>
Run Code Online (Sandbox Code Playgroud)
现在,它存在于我的本地存储库中,该类存在于WEB-INF/classes/my/package/myservices.myservices然而,当我去使用时,我得到的包my.package不存在.的Intelli-J知道要改变myservices成my.package.myservices,而是试图import似乎不工作.
对于这种战争依赖,我需要做些什么特别的事吗?
我目前正在使用二进制格式化程序(Remoting)来序列化和反序列化对象以便在我的LAN周围发送.
我最近从2.0升级到.NET 3.5.3.5有没有引入任何新类型来提高序列化性能?
我已经看过了DataContractSerializer,但这会将任何内容序列化为基础XML ...这必须增加内存占用.
什么是在LAN上发送对象的最快串行器?我不关心互操作或版本控制...... 我需要速度!
我对第三方开源替代品持开放态度.
我无法远程进入任何机器来拯救我的生命!我已经尝试了所有可以找到的东西.如果有人可以排除故障或指导我,我会很感激,因为这将是一个添加到我的域名的好工具.
建立:
脚步:
enable-pssremoting done! on all machines trustedhosts configured with * or client machine added Firewalls with public profile off just in case
Enter-PSSession -ComputerName wsustest -Credential wsustest\administrator Enter-PSSession -ComputerName epizzi-pc -Credential epizzi-pc\administrador Enter-PSSession : Connecting to remote server epizzi-pc failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x80090311 occurred while using Kerberos authentication: There are currently no logon servers …
这本来是一个更冗长的问题,但现在我构建了一个较小的可用示例代码,因此原始文本不再相关.
我有两个项目,一个包含一个没有成员的结构,名为TestType.该项目由主项目引用,但程序集不包含在可执行文件目录中.主项目创建一个新的app-domain,它使用所包含程序集的名称注册AssemblyResolve事件.在主app-domain中,处理相同的事件,但它手动从项目资源加载程序集.
然后新的app-domain构建自己的TestType版本,但字段多于原始字段.主app-domain使用虚拟版本,新app-domain使用生成的版本.
当调用 在其签名中具有TestType的方法时(即使只是简单地返回它就足够了),它似乎只会使运行时不稳定并破坏内存.
我使用的是.NET 4.5,在x86下运行.
DummyAssembly:
using System;
[Serializable]
public struct TestType
{
}
Run Code Online (Sandbox Code Playgroud)
主要项目:
using System;
using System.Reflection;
using System.Reflection.Emit;
internal sealed class Program
{
[STAThread]
private static void Main(string[] args)
{
Assembly assemblyCache = null;
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs rargs)
{
var name = new AssemblyName(rargs.Name);
if(name.Name == "DummyAssembly")
{
return assemblyCache ?? (assemblyCache = TypeSupport.LoadDummyAssembly(name.Name));
}
return null; …Run Code Online (Sandbox Code Playgroud) 我正在一个.Net网站上工作,该网站将有1000个并发用户.
我正在考虑将业务组件保留在Web服务器上的应用服务器和UI组件上.数据库(MS SQL Server 2005)将托管在另一台服务器上.我打算也使用负载平衡.
鉴于此,如果我想拥有最佳的应用程序性能和可扩展性,那么从Web服务器到应用服务器的最佳通信方式是什么?
我通过远程处理暴露了单例类,我遇到了一些问题.在我的服务器中,我有:
TcpChannel channel = new TcpChannel( Settings.Default.RemotingPort );
ChannelServices.RegisterChannel( channel, false );
RemotingConfiguration.RegisterWellKnownServiceType(
typeof( RemotableObject ), "RemotableObject",
WellKnownObjectMode.Singleton );
Run Code Online (Sandbox Code Playgroud)
RemotableObject是一个继承MarshalByRefObject的单例对象.
我的客户通过以下方式连接到它
remoteObject = (RemotableObject)Activator.GetObject(
typeof( RemotableObject ),
string.Format( "tcp://{0}:{1}/RemotableObject", serverIP, serverPort ) );
Run Code Online (Sandbox Code Playgroud)
就远程处理而言,一切都很好,但是当我在服务器代码中访问单例对象时,如下所示:
int someValue = RemotableObject.Instance.SomeDynamicValue;
Run Code Online (Sandbox Code Playgroud)
它访问与客户端不同的实例.我还验证了RemotableObject中的私有构造函数在调试时会被击中两次.
如果我通过我的服务器代码中的远程处理获得RemotableObject的实例,我可以获得所需的行为,但有没有办法可以从服务器访问与客户端相同的对象而没有远程处理开销?
我被告知的一切都说WCF应该至少和远程处理一样快.我有一个特定的场景,然而,它甚至没有接近,我想知道是否有人可以发现一些明显的我做错了.我正在研究用wcf替换远程处理以进行进程内appdomain通信繁重的可能性.这是代码:
[ServiceContract]
interface IWorkerObject
{
[OperationContract] Outcome DoWork(Input t);
}
[DataContract]
[Serializable]
class Input
{
[DataMember] public int TaskId { get; set; }
[DataMember] public int ParentTaskId { get; set; }
[DataMember] public DateTime DateCreated { get; set; }
[DataMember] public string TextData { get; set; }
[DataMember] public byte[] BinaryData { get; set; }
}
[DataContract]
[Serializable]
class Outcome
{
[DataMember] public string Result { get; set; }
[DataMember] public string TextData { get; set; }
[DataMember] public byte[] …Run Code Online (Sandbox Code Playgroud) 我有一个使用OLE自动化编组器的DCOM客户端和服务器应用程序.它们在同一台PC上运行时工作正常,但当服务器位于不在同一域的不同PC上时,我得到E_ACCESSDENIED(0x80070005).
服务器PC配置了dcomcnfg,以便为我在客户端上指定的登录名和密码的用户提供对任何DCOM对象的所有访问权限.ServerApp及其类型库已在服务器pc上注册.
类型库也在客户端PC上注册.我直接在ClientApp中指定服务器名称,因此据我所知,客户端PC上不需要dcomcnfg配置.
具有服务器名称,登录名,域名和密码的CreateInstanceEx()工作正常.它返回IUnknown,同时在服务器PC上启动ServerApp.
但是当我尝试使用QueryInterface()获取服务器支持的接口时,我得到了E_ACCESSDENIED.
分析安全事件日志,我有两条记录:
首先,我在ClientApp中指定其凭据的用户成功进行网络登录.当我调用CreateInstanceEx()时会发生这种情况.
接下来,我在客户端PC上登录的用户登录尝试失败.由于两台PC不在域中,因此服务器PC不知道该用户.
现在,为什么这个用户会登录到服务器,特别是当我调用所有东西的QueryInterface时?
研究CreateInterfaceEx参数,似乎有某种模仿机制正在进行中.但目前还不清楚是谁冒充了谁.涉及三个用户凭据:
ServerApp在服务器PC上运行的用户(在dcomcnfg中配置).
连接时ClientApp指定凭据的用户.
ClientApp在客户端PC上运行其凭据的用户.
无论你如何看待它,如果涉及#3,那么它就是一个用户.如果DCOM要在服务器PC上识别/模仿#3,为什么我需要指定#2的凭证?到了什么地步?
DCOM冒充#2似乎是合乎逻辑的,因为这是我明确指定为我的凭据.但为什么第二次登录尝试呢?
有人可以解释模仿是如何工作的,还有一种方法可以忽略它并以dcomcnfg中指定的用户身份运行?