What is the difference between CAO and SAO in Remoting? - c#

What is the difference between CAO(Client-activated objects ) and SAO(Server-activated objects) in Remoting?
Hoping for some good answers clearing citing the differences. any links or explanations are welcome.
I have googled about this but there wasnt much good answers in it either.

An instance of an remote class can be activated by either the server or client.
Client-activated objects are created on the server as soon as the client calls New or the Activator object.
(Basically, each client-activated instance of a remote class has a 1:1 mapping with a particular client. Each client holds its own personal instance of the remote class.)
Server-activated objects are created by the server only when the client invokes the first method through the local proxy.
(server-activated objects can be declared as Singleton or SingleCall objects. A Singleton object has exactly one instance to serve all possible clients. A SingleCall object requires that each incoming call is served by a new instance.)
Please check the below 2002 MSDN magazine about remoting. But as advised by #John Saunders, you should better use WCF. In WCF, you don't need to learn different technologies for webservices, remoting or messaging communication. These are all under the umbrella of WCF.
http://msdn.microsoft.com/en-us/magazine/cc188927.aspx#S6

Related

WCF CallBack Object logic

In the wcf duplex project I am working on, proxy is created and opened using the following 3 lines:
InstanceContext context = new InstanceContext(new MyCallbackObjectImplementingCallbackContract());
_proxy = new ServiceClient(context);
_proxy.Open();
I have a couple of questions here:
Lets say my callback contract has just 3 methods(operation contract) and on my callback class, on top of just implementing those 3 I have like 10 more methods.
I found by debugging on server side when
OperationContext.Current.GetCallbackChannel<IMyCallbackContract>() is called
the object returned has only the methods with attribute 'OperationContract', and not the whole object. What is the magic behind the scenes. Also, is it not a bad design to have bunch of extra(not contract implementations) methods on call back class, if so what impact could it possibly have?
_proxy.open() metadata says object to transition from the created state into the opened state. I don't quite get what that means?
Question #1: Yes, WCF only looks for methods marked with OperationContract attribute. It creates proxies using the old Remoting RealProxy/TransparentProxy mechanism. Basically, WCF looks for operations in the contract interface, not in a class that implements the interface. It also proxies the contract interface, and not an implementation class.
As for the design question, it depends. As long as the other methods help the operation methods fulfill their contract, there is no problem. But if the other methods implement a different responsibility, then as it sounds, such design violates the single responsibility principle.
Question #2: in WCF, channel proxies inherit CommunicationObject. This object is not stateless, it tracks state of communication over the channel. Moreover, it can hold a session on the remote side, which is an expensive and limited resource. For these reasons, communication object should be treated much like database connection: open it, execute the operation, then Close() or Abort(). You can find more details in this MSDN topic.

How to get references to already instantiated remote objects using WCF?

I’ve just read Ingo Rammer's article titled “From .NET Remoting to the Windows Communication Foundation (WCF)”, on the MSDN website (http://msdn.microsoft.com/en-us/library/aa730857(v=vs.80).aspx).
I still have one doubt, though, and I hope someone can help me.
In session “Step 3 - Use Sessions instead of Client-Activated Objects”, which covers exactly the kind of use of Remoting we make here in our company, he has shown how to obtain and use references to remote objects instantiated on the other side (server’s side). However, in our case, we don’t instantiate these objects on the server’s side at the moment the client requests references to them. The objects already exist on the server’s side (they were previously instantiated), and I just want to get references to these already active objects.
How do we do this today, using Remoting? We have an “Object Server” object (which derives from MarshalByRefObject). This object is available through an URL “tcp://localhost:9002/ObjectServerInstance”. Remote applications can get a reference to it using Activator.GetObject. This Object Server object implements an interface IObjectServer, that declares a method with the following signature:
Object GetObject (string objTag);
Client applications use the reference to this Object Server object to call its GetObject method, passing an object tag string as parameter (Ex: “Portfolio”). This method then returns a reference to the Portfolio object, which has previously published itself before the Object Server object using this tag “Portfolio”. The Portfolio object also derives from MarshalByRefObject, of course. And it isn’t instantiated only when a remote client asks for a reference to it, it was already instantiated on the server.
Of course, this could be done differently. Each object that might be accessed remotely could programmatically use its own objectUri to publish itself before the Remoting layer on the server’s side (Ex: “tcp://localhost:9002/MyObjectInstance”), and on the clients’ side we could use Activator.GetObject directly to get each object’s reference. But this is irrelevant to the point I’m raising. Anyway, the server objects would already exist when they publish themselves before the Remoting layer.
Was I clear enough? Do you see a way to do this using WCF?
Looking at the code at the link you provided, it seems to me that you need to modify the GetInstanceMethod implementation of the IRemoteFactory interface to return an existing object, instead of creating a new one.
public interface IRemoteFactory
{
IMySessionBoundObject GetInstance();
}
public class RemoteFactory : MarshalByRefObject, IRemoteFactory
{
public IMySessionBoundObject GetInstance()
{
// Return an already existing object, instead of a new one.
return MyAlreadyExistingSessionBoundObject;
}
}
There is a solution to your problem, but be warned it goes against the grain of WCF and the concepts of service orientation.
Maintaining a sessionful state on the server has all sorts of ramifications and potential pitfalls. You introduce coupling between the client(s) and the server and have to think carefully what you will do in the case of corrupt state and exceptions.
The solution is a bit too long for a Stack Overflow post, so I've posted it on github here.
I can't claim any credit for the solution - most of it comes from a blog post I read somewhere (I'll update this once I remember what it was). It is interesting from the point of view that it uses some fairly advanced WCF low-level code - and it great for furthering your understanding on how WCF works.
I would further iterate that if there is anyway of avoiding implementing this in a production environment to go down that route.

Share an instance between multiple projects

I am working in VS 2008 C# and need to share an instance of an object created in one project with another project. I tried creating a static class in project1 and adding it as a link to project2, but the information wasn't saved. The static class was written in project1.
//object o = new object
//project1.staticObject = o
//project2.object = project1.staticObject
When I tried something like above, project2.object would be null. By adding a class as a link, is it creating a new instance of the static class in project2 or is it referencing the same class? If it is referencing the same class, shouldn't any information saved into the static class from project1 be accessible by project2? I know this isn't the most elegant manner of sharing data, but if anyone would help with this problem or provide a better manner of doing it, I would greatly appreciate it.
Thanks in advance.
Projects run in separate processes, so they can't share data in this manner. You'll need to persist the data in another type of store. I recommend using a database (hey, 20 gazillion websites, stock trading apps, airlines, etc can't be wrong).
If you don't want to use a database, you could open an IP connection between instances of the app and have a thread send packets of data to sync back and forth between the applications. Or, in your "server" app, add a web service that each process would call to update and retrieve information.
If you need really high-speed communication between the processes, sockets with a peer or star topology is a good way to go. If you're okay with some latency, having a web service (which works fine even if these aren't web apps) or a database could be a good solution. The right approach depends on your application.
WCF could also solve this problem. It effectively wraps the IP/socket layer and provides some nice object persistence/remote control capabilities, but I find it overly complex for most applications.
To share a single instance of an object among different processes (that's what I think you are intending to do) you need something that will maintain that object's state. You can look at the WCF and how to set up it's behaviour to act as a singleton so essentially every requester gets the same instance across the board.
http://msdn.microsoft.com/en-us/magazine/cc163590.aspx
Creating the link creates only applies to the source code. When you compile each project, it then has that single class definition available in both projects. The process you took does nothing for instances during runtime for sharing.
You can look at WCF or .NET Remoting, although .NET Remoting is now officially replaced by WCF.
If you are talking about sharing the same object between two processes, you can do that, the concept is called memory-mapped files. Here is some starter docs from msdn.
Though the docs and API use the term "FileMapping" quite a bit, you can use it just for sharing memory between two processes.
In .NET 4.0, you can use the System.IO.MemoryMappedFiles namespace. For your case, looks like .NET 3.5, you'll have to use some sort of interop to use the Win API.

What is the major use of MarshalByRefObject?

What's the purpose for MarshalByRefObject?
Remoting; it means that between AppDomains or machines, rather than serialize and transfer the object, the object stays at one end and a proxy is created at the other. All method calls to the proxy are intercepted and the call is transmitted as RPC wiki, msdn, causing the method to execute on the other machine (typically serialising the arguments and return value).
Note: this can lead to unexpectedly "chatty" interfaces. The object/proxy/RPC approach is now less preferable to approaches with an explicit service boundary; Microsoft now recommends WCF wiki, msdn instead of remoting.
Another important use of MarshalByRefObject is for implementing AOP via remoting sink-chains.
If you have an object that derives from ContextBoundObject (which itself derives from MarshalByRefObject) you can instantiate it in a separate Context within the same AppDomain and have communications between objects automatically go through the Remoting proxy system - allowing you to plug custom sinks into the Remoting sink-chain.
This ultimately allows you to 'decorate' method calls to your objects and implement cross-cutting services, such as logging and security etc.
it basic use is for support access of objects between two appdomains and these appdomains can be on the same computer or in the different computers via remoting.
See Here
Any object outside the application domain of the caller application should be considered as Remote Object. A Remote Object that should be derived from MarshalByRefObject Class. Any object can be changed into a Remote Object by deriving it from MarshalByRefObject. Objects without inheriting from MarshalByRefObject are called Non-remotable Objects.

Why are Static Methods not Usable as Web Service Operations in ASMX Web Services?

I just wanna learn why I can't static web methods in web services ? Why is it restricted ?
Can some body give me concise explanation of this.
The answer is: because you can't.
It's not designed that way. The design is that an instance of the web service class will be created, and then an instance method will be called.
I can only guess why Microsoft designed it that way. To know for sure, you'd have to ask them. Consider:
There's no particular benefit to permitting static methods. Anything you can do with a static method, you can also do with an instance method.
A [WebService] class is not meant to be some arbitrary class that happens to be used as a web service. It's meant to be a class that you created for the purpose of exposing web service operations. As such, there is no need to support classes that already exist and already have static methods.
The SOAP Header implementation permits your class to contain an instance field of a type deriving from the SoapHeader class. This field will be filled with an incoming SOAP header and/or will contain the SOAP Header to be returned. You could not do this with a static field, as it would be overwritten with each request.
As I said, these are all guesses. The correct answer to the question is, "you can't because that's how Microsoft designed it. If you want to know why they designed it that way, you need to ask them".
FWIW, I just checked, and it does not appear that WCF permits static methods to be operations either.
When a client creates an object for your web service, what they are really creating is a proxy object to that web service. This proxy object handles things like opening and closing your connections for you as well as all the overhead of actually working with the web service. A static method call would be difficult to manage. The "static proxy" for lack of a better word would have to do all of things that the instance of the proxy object is doing each and every time a client called one of the static methods, thus adding massive overhead.

Categories