欢迎光临
我们一直在努力

建站超值云服务器,限时71元/月

implementation

the sample solution of the remote callbacks implemenation is divided into several projects:

contractobject – common abstract definitions (see the above)
remotecallbacklib – remotecallback custom attribute (see the above)
remoteobjecta – classic .net object hosted in the hostserver
remoteobjectx – .net service (com+) hosted in the hostserver
remoteobjectws – web service hosted in the iis
hostserver – console server program
remotewindowsform – windows form client program
also the solution included the following config files:

hostserver.exe.config – the remoting config info for objects hosted by hostserver
remotewindowsform.exe.config – the config info for remoting objects using by this client

remotecallbacklib

the following code snippet shows the implementation of the remotecallbackattribute. its design is based on the refection of the "parent" assembly, where located all metadata of the callback object. the remotecallbacklib is built into the separate assembly which it can be reused by another remoting clients.

namespace rkiss.remotecallbacklib
{
   [attributeusage(attributetargets.field)]
   public class remotecallbackattribute : attribute
   {
      private string _desc;
      private string _protocol;
      private int _port;
      public string desc
      {
         get { return _desc; }
         set {_desc = value; }
      }
      public string protocol
      {
         get { return _protocol; }
         set {_protocol = value; }
      }
      public int port
      {
         get { return _port; }
         set {_port = value; }
      }
      public remotecallbackattribute() : this("tcp", 0) {}
      public remotecallbackattribute(string sprotocol) : this(sprotocol, 0) {}
      public remotecallbackattribute(string sprotocol, int iport)
      {
         protocol = sprotocol;
         port = iport;
      }
   }

   // creating remoting stuff based on the properties of the callbackattribute
   // note that all callback class have to located in the same (parent) assembly!
   public class remotecallbacksubscriber
   {
      private hashtable ht = hashtable.synchronized(new hashtable());
      private string site  = "localhost";
        
      public remotecallbacksubscriber(object parent)
      {
         type typeparent = parent.gettype();
                        
         foreach(fieldinfo fi in typeparent.getfields())
         {
            foreach(attribute attr in fi.getcustomattributes(true))
            {
               if(attr is remotecallbackattribute)
               {
                  remotecallbackattribute rca = attr as remotecallbackattribute;

                  // open in/out channel
                  int port = rca.port;
                  if(port == 0)
                  {
                     random rdmport = new random(~unchecked((int)datetime.now.ticks));
                     port = rdmport.next(1, ushort.maxvalue);
                  }

                  // create channel
                  ichannel channel = null;                
                  if(rca.protocol == "tcp")    
                     channel = new tcpchannel(port);
                  else
                  if(rca.protocol == "http")
                     channel = new httpchannel(port);
                  else
                     throw new exception(string.format("the {0} is not recognize protocol.", rca.protocol));

                  // register channel
                  channelservices.registerchannel(channel);

                  // register a callback object
                  string nameofcallbackobject = fi.fieldtype.fullname;
                  type typeofcallbackobject = typeparent.assembly.gettype(nameofcallbackobject);
                  remotingconfiguration.registerwellknownservicetype(
                              typeofcallbackobject,
                              nameofcallbackobject,
                              wellknownobjectmode.singleton);

                  // create proxy
                  string urlofcallbackobject = string.format(@"{0}://{1}:{2}/{3}",
                              rca.protocol, site, port, nameofcallbackobject);
                  object proxycb = activator.getobject(typeofcallbackobject, urlofcallbackobject);
                  fi.setvalue(parent, proxycb);
                  //
                  //store into the ht
                  ht[fi.name] = channel;
               }
            }
         }
      }
      public ichannel this [string nameofcallback]
      {
         get { return ht[nameofcallback] as ichannel; }
      }
   }
}

remoteobject (a , x and ws)

the design pattern of the remoting methods is the same for any of these remoting objects. the following code snippet shows the remoteobjecta class derived from the marshalbyrefobject class and irmobject interface.

using rkiss.remoteobject;    // abstract definitions

namespace rkiss.remoteobjecta
{    
   public class rmobjecta : marshalbyrefobject, irmobject
   {
      public rmobjecta()
      {
         trace.writeline(string.format("[{0}]rmobjecta activated", gethashcode()));    
      }
      public string echo(string msg)
      {
         trace.writeline(string.format("[{0}]rmobjecta.echo({1})", gethashcode(), msg));
         return msg;
      }
      // stateless callbacks
      public string givemecallback(int timeinsec, string ticketid, object objwire)
      {
         remotecallback wire = objwire as remotecallback;
         bool bprogress = true;
         callbackeventargs cea = new callbackeventargs();
         cea.ticketid = ticketid;
         cea.state = "running …";
         cea.sender = gettype().tostring();

         wire(cea.sender, cea);
         while(timeinsec– > 0 && bprogress)
         {
            thread.sleep(1000);
            cea.state = timeinsec;
            bprogress = wire(cea.sender, cea);
         }
         cea.state = bprogress?"done":string.format("aborted at {0}", ++timeinsec);
         wire(cea.sender, cea);
         //
        trace.writeline(string.format("[{0}]rmobjecta.givemecallback({1}, {2}, {3})",
                        gethashcode(), timeinsec, ticketid, wire.gettype().fullname));
        return ticketid;
      }
   }
}

there are implementation of two methods of the irmobject interface in the object. the first one – echo has a test purpose, the other one – givemecallback simulated some time consuming work with notification of the method state using the remoting callback mechanism. the method state is wrapped and serialized by the callbackeventargs object.

now i will show you only differencies in the following remote objects:

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 »
分享到: 更多 (0)

相关推荐

  • 暂无文章