Welcome to MSDN Blogs Sign in | Join | Help

I have heard from quite a few folks running into an issue where the IpcServerChannel would throw trying to initialize after a restart.

IpcServerChannel by default creates pipes in exclusive mode (no other process can listen on the same pipe name). There is a known issue with pipes -- that if there is a client side handle open to a now defunct server pipe, no further server instances are possible till a timeout cleans up the client side handles.

You can work around this issue by setting exclusiveAddressUse="false" on the server channel config. Be aware of the implications though -- any other process can start listening on the same pipe as your server. Hopefully this issue will get resolved in future releases.

In most cases it is not quite obvious, but in scenarios where a client receives callbacks, or subscribes to events on the server, you need to make sure that the lease on the client object doesnt expire -- registering a sponsor for the client object is one solution.

The issue gets hard to diagnose for the event case, since there is not indication that the server failed to raise an event on the client.

The Microsoft Operations Manager team has a number of development openings.If you are interested in working on cutting edge technology in enterprise monitoring and management space, this is your chance. Microsoft Operations Manager (MOM 2005) is already revolutionizing the event and performance management market, come work on the next version which will even simplify managing the enterprise. Please feel free to ping me if you would be interested.

Thanks

Now that .net Framework 2.0 is released -- a list of new features in remoting is in order. Following is a list of new features added to remoting:

1. IPCChannel: A new channel based on named pipes form x-process (same machine) communication. Its more secure and performant than the previous best performer the tcp / binary channel.

2. Authentication / Authorization Support: IPC and TCP channels now have inbuilt support for authentication (identification / impersonation) and authorization. This removes the use of custom security sinks.

3. Timeout on TcpChannel: This was one of the pain points before. Now the client can specify a timeout on the tcp channel to avoid deadlocks

4. IPv6  support: Tcp and HTTP channels now are ipv6 aware

5. Better NLB support: By making the client side connection cache configurable, earlier issues with NLB and sticky connections has been eliminated.

As far as binary serialization goes the new big feature is version tolerant serialization which allows type versioning fidelity.

This has been a frequently asked question about whether there is timeout support on remoting tcp channel. In 2.0 we have added support for timeouts. Unfortunately the support is missing in beta2 -- but should be available when 2.0 is released. The configuration is similar to the HTTP channel. Note that this timeout only affects read / write from native sockets. Connect timeout is not controlled via this setting. Also note that the timeout would be approximate and not a method level but a channel level setting.

After working on remoting for about five years (almost seven on the .net framework) I am changing focus and work in application development space. Thus I have now moved to the Microsoft Operations Manager team. I hope to continue to blog about remoting about new features being added in 2.0. Remoting has come a long way since v1 and 2.0 should significantly have better usability, security and performance.

Please keep sending me mail about any remoting related issues and I will forward them to the right contacts :).. Take care.

This has been a common ask to add some authorization support on remoting channels. During Beta1 remoting added support for authentication and encryption on the TCP channel. In Beta2 there is a new feature which lets you authorize connections based on IP address or client identity. To authorize connections implement the following interface:

    public interface IAuthorizeRemotingConnection
    {
        bool IsConnectingEndPointAuthorized(EndPoint endPoint);
        bool IsConnectingIdentityAuthorized(IIdentity identity);
    }

IsConnectingEndPointAuthorized would be invoked each time a new connection is made to the server -- if the return is false the connection would be dropped. IsConnectingIdentityAuthorized will be invoked if authentication is enabled and it lets the server decide whether the connecting identity should be allowed to make requests to the server.

Use the new TcpServerChannel constructor         public TcpServerChannel(IDictionary properties, IServerChannelSinkProvider sinkProvider, IAuthorizeRemotingConnection authorizeCallback) to plugin this interface. You could also do it through config using authorizationModule="authImpl, assemblyName"

There are config setting changes for Tcp channel authentication in .net framework 2.0 Beta2. Here is a sample server configuration, Note that secure="true" gives a setting of TokenImpersonationLevel.Identify and ProtectionLevel.EncryptAndSign:

<configuration>
      <system.runtime.remoting>
            <application name="BVTServer">
                  <service>
   <wellknown mode="SingleCall" type="Factory, server" objectUri="Factory.soap" />
                  </service>
                  <channels>
                        <channel ref="tcp" port="8000" secure="true" impersonate="true" protectionLevel="EncryptAndSign"/>
                  </channels>
            </application>
      </system.runtime.remoting>
</configuration>

Here is the corresponding client side config:

<configuration>
   <system.runtime.remoting>
      <application>
         <client url="tcp://localhost:3300/BVTServer">
            <activated type="SimpleServer, server"/>
         </client>
         <channels>
         <channel ref="tcp" secure="true" tokenImpersonationLevel="Impersonation" protectionLevel="EncryptAndSign"/>
         </channels>
     </application>
   </system.runtime.remoting>
</configuration>

Another change in Beta2 is that the client principal now flows in Thread.CurrentPrincipal.

Remoting does support stateful connections. You could use singleton or client activated objects to keep object state. This object state is not persisted however. If the server appdomain is unloaded all remoting state will be lost. Not only will the state be lost but client-activated objects will not be available. You will get a "service not found" exception if you try to use a proxy to a non-existent CAO.

If you have a recycle the server scenario, then you are required to use wellknown objects. Wellknown objects are always available when the endpoint is listening, so you need not worry about whether the server has been recycled or not. That said you have to carefull not to depend on any state within the wellknown object.

RemotingServices.Disconnect is probably one of the confusing APIs in remoting. It doesnt correspond to RemotingServices.Connect, but rather to RemotingServices.Marshal. Disconnect is a server side API to disconnect objects which are currently published via remoting. You might have noticed an exception if Disconnect is called on a remoting proxy instead.

This API is can be used to basically "unregister" an object. Note, that any current active invokations on the object would still succeed.

ps. It feels good to be blogging again after more than a month.

Thanks to all those who responded to Call for remoting apps... We will evaluate what remoting applications best fit our criteria and will contact you individually. Thanks again for helping in the remoting compatibility effort.

The .net remoting team is looking for customers to help us with compatibility. If you have existing standalone remoting apps based on v1.0 and v1.1 of the framework and are willing to help us ensure remoting compatibility with future versions of the framework, we will like to hear from you.

If anyone is interested please send mailto:manishg@microsoft.com or mailto:aprabhu@microsoft.com

Thanks

Cloning MarshalByRefObjects can lead to some unexpected behaviour. When a MBR object is marshalled, it gets an unique identity which contains a unique URI to identify this object in the appdomain. When an external call is made to this object it is identified by this URI. An identity once created doesnt change each time the object is marshalled. Now if an MBR object with its identity set is cloned using Object.MemberwiseClone(since this deep clones all private/public fields as well) the cloned object would get the same identity. If the clone is marshalled out, wouldnt get a new identity since it already has one. Thus if calls are made to the cloned object, the invocation could actually be done on the original object, which could lead to some really unwanted results. So please be extra careful while cloning MBRs when the cloned object could potentially be marshalled as well.

In v2.0 of the framework, MBR probably would have a clone helper which would null out the identity after cloning.

If you set machineName="foo.com" in the server side remoting config (to avoid using ip addresses) and probably need to deploy the same config on multiple servers use machineName="$hostName" and remoting will substitute this with the current host dns qualified name. This way you dont have to hardcode any machinenames in config.

Note: this is only available on the server channel config. On the client, as it might be obvious the full server name is required.

A CLR type instance can be activated remotely in the following ways:


1. Through Config: This is probably the most common way. Use the client tag under system.runtime.remoting to register a type to go remote:
<configuration>
  <system.runtime.remoting>
    <application>
      <client>
        <wellknown type="Hello.HelloService, Hello" url="http://localhost:8000/HelloService.soap" />
        <activated type="Hello.HelloActivatedService, Hello" url="http://localhost:8000" />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>

2. RegisterWellKnownClientType or RegisterActivatedClientType: If using a configuration file is not suitable, use these RemotingConfiguration APIs to register types to go remote programmatically.

3. Activator.CreateInstance: (for CAO) Use CreateInstance with the UrlAttribute to activate types remotely. CreateInstance could be used when you need to activate the same type on different servers. The other two methods are static per appdomain, meaning once registered all type activations are done remotely. CreateInstance with UrlAttribute gives a way to selectively activate types remotely.

4. Activator.GetObject: This is the CreateInstance equivalent for WKO. This is a way to generate wellknown proxies for the same type at different endpoints

5. RemotingServices.Connect: This is just an alias for Activator.GetObject. Does the exact same thing

 

More Posts Next page »
 
Page view tracker