Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. remoting "newbie" questions

remoting "newbie" questions

Scheduled Pinned Locked Moved C#
sysadminsalesworkspace
9 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    Palladino
    wrote on last edited by
    #1

    Hi, I am implementing a application that uses remoting that is generating some doubts as to best practices, scalability possibility, round trips on the net and things like this. I would like to know which the "better" form of doing what needed. (I am afraid of giving a shot in my foot! ;-)) Grossly, I have the following assemblies (scenery for questions): -------------------------- Model.dll - It contains the classes that model tables for classes and lines for collections - Distributed in the client and server. IRules.dll - Interface for the rules that will be activated in the server (that accesses a DAL, and so, so...) - Distributed in the client and server. Rules.dll - Implementation of the defined interfaces in IRules - Distributed in the server. -------------------------- Considering these components, the classes would be something as:[Serializable()] public class ModelCustomer { public string Code; public string Name; } public interface IRulesCustomer { bool Insert(Model.ModelCustomer customer); } public class RulesCustomer : MarshalByRefObject, IRules.IRulesCustomer { public virtual bool Insert(Model.ModelCustomer customer) { //customer instance validation //Call DAL class and outher things } } -------------------------- In the server, my configuration file is it something as:

    <configuration>  
       <system.runtime.remoting>  
          <application>  
             <channels>  
                <channel ref="http">  
                    <serverProviders>			  
                        <formatter ref="binary" typeFilterLevel="Full"/>  
                    </serverProviders>  
                </channel>  
             </channels>  
             <service>  
                <wellknown   
                   mode="SingleCall" objectUri="RulesCustomer.rem"  
                   type="Rules.RulesCustomer, Rules" />  
    	    <activated type="Model.ModelCustomer, Model" />  
             </service>  
          </application>  
       </system.runtime.remoting>  
    </configuration>  
    

    -------------------------- In the client, he resembles with:

    <configuration>  
      <system.runtime.remoting>  
        <application>  
          <channels>  
             <channel ref="http">  
                <clientProviders>			  
                   <formatter ref="binary" />  
                &
    
    L 2 Replies Last reply
    0
    • P Palladino

      Hi, I am implementing a application that uses remoting that is generating some doubts as to best practices, scalability possibility, round trips on the net and things like this. I would like to know which the "better" form of doing what needed. (I am afraid of giving a shot in my foot! ;-)) Grossly, I have the following assemblies (scenery for questions): -------------------------- Model.dll - It contains the classes that model tables for classes and lines for collections - Distributed in the client and server. IRules.dll - Interface for the rules that will be activated in the server (that accesses a DAL, and so, so...) - Distributed in the client and server. Rules.dll - Implementation of the defined interfaces in IRules - Distributed in the server. -------------------------- Considering these components, the classes would be something as:[Serializable()] public class ModelCustomer { public string Code; public string Name; } public interface IRulesCustomer { bool Insert(Model.ModelCustomer customer); } public class RulesCustomer : MarshalByRefObject, IRules.IRulesCustomer { public virtual bool Insert(Model.ModelCustomer customer) { //customer instance validation //Call DAL class and outher things } } -------------------------- In the server, my configuration file is it something as:

      <configuration>  
         <system.runtime.remoting>  
            <application>  
               <channels>  
                  <channel ref="http">  
                      <serverProviders>			  
                          <formatter ref="binary" typeFilterLevel="Full"/>  
                      </serverProviders>  
                  </channel>  
               </channels>  
               <service>  
                  <wellknown   
                     mode="SingleCall" objectUri="RulesCustomer.rem"  
                     type="Rules.RulesCustomer, Rules" />  
      	    <activated type="Model.ModelCustomer, Model" />  
               </service>  
            </application>  
         </system.runtime.remoting>  
      </configuration>  
      

      -------------------------- In the client, he resembles with:

      <configuration>  
        <system.runtime.remoting>  
          <application>  
            <channels>  
               <channel ref="http">  
                  <clientProviders>			  
                     <formatter ref="binary" />  
                  &
      
      L Offline
      L Offline
      LongRange Shooter
      wrote on last edited by
      #2

      Marcelo The first thing you should be aware of: by making your object Single Call, the object will be created and destroyed each time it is called. If you expect to have a high volume of calls made, you may consider establishing it as a Singleton and create a custom lease time. For scalability it is VERY important that you always consider your deployment from the aspect of what is called 'chunky calls'. If you have two processes as such: 1. create HTTP channel 2. call Activator.GetObject 3. call to init 4. call to get first info 5. call to get second piece 6. call to get third piece 7. display information -VS- 1. create HTTP channel 2. call Activator.GetObject 3. call to get large object -- server object does 3-6 of prior process 4. display information you will find the second process to SCREAM while the first process will crawl like a snail. Secondly, your use of BinarySerializer is good. The SOAP serializer is horrible. However if is at all possible to remove the server from HTTP and make it a pure TCP client, you will have even faster throughput and better results. There are several other considerations to make as well as determining if remoting is truly the best implementation for you solution. If you read the FAQ here[^], then you can check it out. _____________________________________________ Of all the senses I could possibly lose,
      It is most often the one called 'common' that gets lost.

      1 Reply Last reply
      0
      • P Palladino

        Hi, I am implementing a application that uses remoting that is generating some doubts as to best practices, scalability possibility, round trips on the net and things like this. I would like to know which the "better" form of doing what needed. (I am afraid of giving a shot in my foot! ;-)) Grossly, I have the following assemblies (scenery for questions): -------------------------- Model.dll - It contains the classes that model tables for classes and lines for collections - Distributed in the client and server. IRules.dll - Interface for the rules that will be activated in the server (that accesses a DAL, and so, so...) - Distributed in the client and server. Rules.dll - Implementation of the defined interfaces in IRules - Distributed in the server. -------------------------- Considering these components, the classes would be something as:[Serializable()] public class ModelCustomer { public string Code; public string Name; } public interface IRulesCustomer { bool Insert(Model.ModelCustomer customer); } public class RulesCustomer : MarshalByRefObject, IRules.IRulesCustomer { public virtual bool Insert(Model.ModelCustomer customer) { //customer instance validation //Call DAL class and outher things } } -------------------------- In the server, my configuration file is it something as:

        <configuration>  
           <system.runtime.remoting>  
              <application>  
                 <channels>  
                    <channel ref="http">  
                        <serverProviders>			  
                            <formatter ref="binary" typeFilterLevel="Full"/>  
                        </serverProviders>  
                    </channel>  
                 </channels>  
                 <service>  
                    <wellknown   
                       mode="SingleCall" objectUri="RulesCustomer.rem"  
                       type="Rules.RulesCustomer, Rules" />  
        	    <activated type="Model.ModelCustomer, Model" />  
                 </service>  
              </application>  
           </system.runtime.remoting>  
        </configuration>  
        

        -------------------------- In the client, he resembles with:

        <configuration>  
          <system.runtime.remoting>  
            <application>  
              <channels>  
                 <channel ref="http">  
                    <clientProviders>			  
                       <formatter ref="binary" />  
                    &
        
        L Offline
        L Offline
        LongRange Shooter
        wrote on last edited by
        #3

        By the way....there is one problem with using a BinaryClientFormatterSink in your application: any fault that occurs on the server side during initialization will return the error that the remoting version is wrong version, expected 1.0 and received (an ugly number) This is due to the exception being sent out in text and the client is expecting a return of the version number. To get around this, I had to incorporate the ability to put the application into debug state. So my code is as follows during init time:

        try
        {
            if (DebugState == false)
            {
        	channel = new HttpChannel(null,new BinaryClientFormatterSinkProvider(),new BinaryServerFormatterSinkProvider());
            }
            else
            {
        	channel = new HttpChannel(null,null,null);     // used to debug errors enabling SOAP
        	runningInDebugMode = true;
        	System.Diagnostics.Debug.WriteLine("TCA Navigator has been requested to run in debug mode.", "Remote Communication Manager");
            }
            channel.Properties\["proxyName"\] = null;
            channel.Properties\["useDefaultCredentials"\] = "true";
            ChannelServices.RegisterChannel(channel);
                }
                ...
        

        Also : setting the channel properties is required to keep the code from trying to locate a proxy server and use that to navigate to the site. This is used assuming your application is internal (though you really would not want to do remoting in the open on the internet). Michael _____________________________________________ Of all the senses I could possibly lose,
        It is most often the one called 'common' that gets lost.

        P 1 Reply Last reply
        0
        • L LongRange Shooter

          By the way....there is one problem with using a BinaryClientFormatterSink in your application: any fault that occurs on the server side during initialization will return the error that the remoting version is wrong version, expected 1.0 and received (an ugly number) This is due to the exception being sent out in text and the client is expecting a return of the version number. To get around this, I had to incorporate the ability to put the application into debug state. So my code is as follows during init time:

          try
          {
              if (DebugState == false)
              {
          	channel = new HttpChannel(null,new BinaryClientFormatterSinkProvider(),new BinaryServerFormatterSinkProvider());
              }
              else
              {
          	channel = new HttpChannel(null,null,null);     // used to debug errors enabling SOAP
          	runningInDebugMode = true;
          	System.Diagnostics.Debug.WriteLine("TCA Navigator has been requested to run in debug mode.", "Remote Communication Manager");
              }
              channel.Properties\["proxyName"\] = null;
              channel.Properties\["useDefaultCredentials"\] = "true";
              ChannelServices.RegisterChannel(channel);
                  }
                  ...
          

          Also : setting the channel properties is required to keep the code from trying to locate a proxy server and use that to navigate to the site. This is used assuming your application is internal (though you really would not want to do remoting in the open on the internet). Michael _____________________________________________ Of all the senses I could possibly lose,
          It is most often the one called 'common' that gets lost.

          P Offline
          P Offline
          Palladino
          wrote on last edited by
          #4

          Hi Michael, Before anything else, thank you for the answers. They helped a lot! In relation to the informed problems in my previous post, your answers took me to do the following: 1 - My model objects don't inherit more of MarshalByRefObject. (only the rules objects inherit now) 2 - My model objects now are marked as [Serializable ()] and they implement the interface ISerializable. 3 - I am not more using CAO. The model object is created in the client and gone by value through methods in my classes of rules. To use "chunky interfaces": Excellent touch, thank you very much! This solves the problem of the roundtrips. To use "Singleton" instead of "SingleCall": humm.... I am still forming an opinion to respect, but own Ingo (in the link that you indicated :-D) says that SingleCall turns easier to make a scalability application. But I understood your point, that is gone back more to performance and use of resources. On the other hand, if I am in an environment with load balance... Now another question: Did I understand certain with relationship to the fact of implementing ISerializable in my model objects? This way they are gone by value, they are not? (like a DataSet, for example) A great hug and thank you very much again, Marcelo Palladino Brazil

          L 1 Reply Last reply
          0
          • P Palladino

            Hi Michael, Before anything else, thank you for the answers. They helped a lot! In relation to the informed problems in my previous post, your answers took me to do the following: 1 - My model objects don't inherit more of MarshalByRefObject. (only the rules objects inherit now) 2 - My model objects now are marked as [Serializable ()] and they implement the interface ISerializable. 3 - I am not more using CAO. The model object is created in the client and gone by value through methods in my classes of rules. To use "chunky interfaces": Excellent touch, thank you very much! This solves the problem of the roundtrips. To use "Singleton" instead of "SingleCall": humm.... I am still forming an opinion to respect, but own Ingo (in the link that you indicated :-D) says that SingleCall turns easier to make a scalability application. But I understood your point, that is gone back more to performance and use of resources. On the other hand, if I am in an environment with load balance... Now another question: Did I understand certain with relationship to the fact of implementing ISerializable in my model objects? This way they are gone by value, they are not? (like a DataSet, for example) A great hug and thank you very much again, Marcelo Palladino Brazil

            L Offline
            L Offline
            LongRange Shooter
            wrote on last edited by
            #5

            The only item that I would say you should make an adjustment to is the ISerializable implementation. The reason I say so is that you have to implement your own serializer/deserializer!!! Just add the [Serializable] attribute. The process of 'going remote' goes through several SinkProviders including the BinarySerializer. So implementing the ISerializable interface just creates redundancy. Now ---> once you get everything set to run with SAO instead of CAO, all you need to do is the following: 1) Get your app finished and working so your server objects are stabilized 2) Set up a stress test if possible 3) Now you can compare the impacts to your app on whether or not you should be Singleton or SingleCall. IMHO -- this ends being based on application process and design rather than just a cookie-cutter decision. For my app, I found that having the objects there was great and the Singletons will eventually be flushed if no activity occurs, but remain when activity is high. For me, I was initializing collections of objects remotely and passing single instances back to the caller. Great setup for a Singleton. If I did not need the populated collections, I probably could get away with the SingleCall. Enjoy! Michael _____________________________________________ Of all the senses I could possibly lose,
            It is most often the one called 'common' that gets lost.

            P 1 Reply Last reply
            0
            • L LongRange Shooter

              The only item that I would say you should make an adjustment to is the ISerializable implementation. The reason I say so is that you have to implement your own serializer/deserializer!!! Just add the [Serializable] attribute. The process of 'going remote' goes through several SinkProviders including the BinarySerializer. So implementing the ISerializable interface just creates redundancy. Now ---> once you get everything set to run with SAO instead of CAO, all you need to do is the following: 1) Get your app finished and working so your server objects are stabilized 2) Set up a stress test if possible 3) Now you can compare the impacts to your app on whether or not you should be Singleton or SingleCall. IMHO -- this ends being based on application process and design rather than just a cookie-cutter decision. For my app, I found that having the objects there was great and the Singletons will eventually be flushed if no activity occurs, but remain when activity is high. For me, I was initializing collections of objects remotely and passing single instances back to the caller. Great setup for a Singleton. If I did not need the populated collections, I probably could get away with the SingleCall. Enjoy! Michael _____________________________________________ Of all the senses I could possibly lose,
              It is most often the one called 'common' that gets lost.

              P Offline
              P Offline
              Palladino
              wrote on last edited by
              #6

              Hi again Michael, Unintentionally to abuse, but already abusing ;) am not sure if I understood what you wanted to say below sentence: theRealCondor wrote: The only item that I would say you should make an adjustment to is the ISerializable implementation. The reason I say so is that you have to implement your own serializer/deserializer!!! The one that I thought about doing is something of the type:

              [Serializable()]  
              public class MyModelObject : ISerializable  
              {  
              private int a;  
              private string b;  
              
              public MyModelObject()  
              {  
              }  
                
              public MyModelObject(int a, string b):base()  
              {  
              this.a = a;  
              this.b = b;  
              }  
                
              protected MyModelObject(SerializationInfo info, StreamingContext context)  
              {  
              this.A = info.GetInt32("A");  
              this.B = info.GetString("B");  
              }  
                
              public int A  
              {  
              get {return this.a;}  
              set {this.a = value;}  
              }  
                
              public string B  
              {  
              get {return this.b;}  
              set {this.b = value;}  
              }  
               
              void ISerializable.GetObjectData(SerializationInfo info,   
              StreamingContext context)  
              {  
              info.AddValue("A", this.a);  
              info.AddValue("B", this.b);  
              }  
              }
              

              For the what could understand I should not make this?! Only use [Serializable()] it didn't work. Can you feel a light (larger still)? :confused: Greetings, Marcelo Palladino Brazil

              L 2 Replies Last reply
              0
              • P Palladino

                Hi again Michael, Unintentionally to abuse, but already abusing ;) am not sure if I understood what you wanted to say below sentence: theRealCondor wrote: The only item that I would say you should make an adjustment to is the ISerializable implementation. The reason I say so is that you have to implement your own serializer/deserializer!!! The one that I thought about doing is something of the type:

                [Serializable()]  
                public class MyModelObject : ISerializable  
                {  
                private int a;  
                private string b;  
                
                public MyModelObject()  
                {  
                }  
                  
                public MyModelObject(int a, string b):base()  
                {  
                this.a = a;  
                this.b = b;  
                }  
                  
                protected MyModelObject(SerializationInfo info, StreamingContext context)  
                {  
                this.A = info.GetInt32("A");  
                this.B = info.GetString("B");  
                }  
                  
                public int A  
                {  
                get {return this.a;}  
                set {this.a = value;}  
                }  
                  
                public string B  
                {  
                get {return this.b;}  
                set {this.b = value;}  
                }  
                 
                void ISerializable.GetObjectData(SerializationInfo info,   
                StreamingContext context)  
                {  
                info.AddValue("A", this.a);  
                info.AddValue("B", this.b);  
                }  
                }
                

                For the what could understand I should not make this?! Only use [Serializable()] it didn't work. Can you feel a light (larger still)? :confused: Greetings, Marcelo Palladino Brazil

                L Offline
                L Offline
                LongRange Shooter
                wrote on last edited by
                #7

                Pallidino said: :confused::confused::confused: Michael responds: Here is what I did that worked and is very simple:

                using System.Runtime.Remoting;
                using System.Collections;

                [Serializable]
                public class WidgetCollection:CollectionBase
                {
                /// /// Allows indexed access of the Widget item collection
                ///
                public WidgetItem this[int index]
                {
                get{return (WidgetItem)this.List[index]; }
                set{this.List[index] = value; }
                }
                ///
                /// Required Add() method def
                ///
                public void Add(WidgetItem item)
                {List.Add(item)}
                ///
                /// Strong typed key access
                ///
                public WidgetItem this(string key)
                {return (WidgetItem) List(key)}
                }

                [Serializable]
                public class WidgetItem
                {
                Sprocket internalSprocket
                Spoke internalSpoke
                DooHickey internalDooHickey
                //public accessors....
                ...
                }

                This construct is used by both the client and server objects. Server creates the WidgetCollection and populates it with Widgets. Both the WidgetCollection and the Widget are marked [Serializable]. So your server object could be like this assuming that you had a server object instance named Server that handled the population of the WidgetCollection, and you already created the Interface object that defines your WidgetManager for your client use:

                public class WidgetManager:MarshalByRefObject, IWidgetManager
                {
                public Widget GetWidget(WidgetKey item)
                {
                WidgetCollection itemList = Server.PopulateWidgets();
                return itemList[item];
                }
                }

                Now.....if you do this, run your remote objects, and get an error that says that {some object} cannot be serialized :doh:, then {some object} has not been marked [Serializable]. In my example, WidgetItem uses a unique object type of Sprocket, Spoke, and DooHickey. I must make certain that all three object type definitions are marked as [Serializable]. You must keep iterating through your object tree until you finally succeed without the 'cannot be serialized' error. So I'm required to add:

                \[Serializable\]
                public class Sprocket()
                {
                    ...existing definition
                }
                \[Serializable\]
                public class Spoke()
                {
                    ...existing definition
                }
                \[Serializable\]
                public class DooHickey()
                {
                    ...existing defi
                
                1 Reply Last reply
                0
                • P Palladino

                  Hi again Michael, Unintentionally to abuse, but already abusing ;) am not sure if I understood what you wanted to say below sentence: theRealCondor wrote: The only item that I would say you should make an adjustment to is the ISerializable implementation. The reason I say so is that you have to implement your own serializer/deserializer!!! The one that I thought about doing is something of the type:

                  [Serializable()]  
                  public class MyModelObject : ISerializable  
                  {  
                  private int a;  
                  private string b;  
                  
                  public MyModelObject()  
                  {  
                  }  
                    
                  public MyModelObject(int a, string b):base()  
                  {  
                  this.a = a;  
                  this.b = b;  
                  }  
                    
                  protected MyModelObject(SerializationInfo info, StreamingContext context)  
                  {  
                  this.A = info.GetInt32("A");  
                  this.B = info.GetString("B");  
                  }  
                    
                  public int A  
                  {  
                  get {return this.a;}  
                  set {this.a = value;}  
                  }  
                    
                  public string B  
                  {  
                  get {return this.b;}  
                  set {this.b = value;}  
                  }  
                   
                  void ISerializable.GetObjectData(SerializationInfo info,   
                  StreamingContext context)  
                  {  
                  info.AddValue("A", this.a);  
                  info.AddValue("B", this.b);  
                  }  
                  }
                  

                  For the what could understand I should not make this?! Only use [Serializable()] it didn't work. Can you feel a light (larger still)? :confused: Greetings, Marcelo Palladino Brazil

                  L Offline
                  L Offline
                  LongRange Shooter
                  wrote on last edited by
                  #8

                  Marcelo, Putting this another way:

                  "With the exception of earlier TCP/IP RPC implementations, in which you even had to worry about little-endian/big-endian conversions,
                  all current remoting frameworks support the automatic encoding of simple data types into th echosen transfer format.
                  The problem starts when you want to pass a copy of an object from server to client. Java RMI and EJB support these requirements, but COM+ for example, did not.
                  The commonly used serializable objects within COM+ were PropertyBags and ADO Recordsets -- but there was no easy way of passing large object structs around.

                  In .NET Remoting the encoding/decoding of objects is natively supported.
                  You just need to mark such objects with the [Serializable] attribute -OR- implement the interface ISerializable and the rest will be taken care of by the framework.
                  This even allows you to pass your objects cross-platform via XML.

                  The serialization mechanism marshal simple data types and subobjects (which have to be serializable or exist as remote objects),
                  and even ensures that circular references (which could result in endless loops when not discovered) don't do any harm.

                  -- Ingo Rammer, Advanced .NET Remoting

                  _____________________________________________ Of all the senses I could possibly lose,
                  It is most often the one called 'common' that gets lost.

                  P 1 Reply Last reply
                  0
                  • L LongRange Shooter

                    Marcelo, Putting this another way:

                    "With the exception of earlier TCP/IP RPC implementations, in which you even had to worry about little-endian/big-endian conversions,
                    all current remoting frameworks support the automatic encoding of simple data types into th echosen transfer format.
                    The problem starts when you want to pass a copy of an object from server to client. Java RMI and EJB support these requirements, but COM+ for example, did not.
                    The commonly used serializable objects within COM+ were PropertyBags and ADO Recordsets -- but there was no easy way of passing large object structs around.

                    In .NET Remoting the encoding/decoding of objects is natively supported.
                    You just need to mark such objects with the [Serializable] attribute -OR- implement the interface ISerializable and the rest will be taken care of by the framework.
                    This even allows you to pass your objects cross-platform via XML.

                    The serialization mechanism marshal simple data types and subobjects (which have to be serializable or exist as remote objects),
                    and even ensures that circular references (which could result in endless loops when not discovered) don't do any harm.

                    -- Ingo Rammer, Advanced .NET Remoting

                    _____________________________________________ Of all the senses I could possibly lose,
                    It is most often the one called 'common' that gets lost.

                    P Offline
                    P Offline
                    Palladino
                    wrote on last edited by
                    #9

                    Michael, I don't have as thanking for this "chat" that we had. For this first moment it is everything OK, thank you very much (really)! With relationship to the Ingo book´s, I tried to buy for here but I didn't get (still)... It was worth, Marcelo Palladino Brazil

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups