connect to a service with .NET remoting in a service - c#

For obscure reasons I need to connect to a service with .NET remoting from WITHIN the service itself.
To clarify:
there's a client application connecting to the service:
IEngine engine = (IEngine)Activator.GetObject(typeof(IEngine), "tcp://169.18.1.100:1966/Engine");
When a certain call is made to the service it loads an AppDomain with a plugin dll which computes something. But now this dll needs to call functions from the service its embedded in and it cant call them directly since it lives in its own AppDomain.
So can I just call this from within the AppDomain?
IEngine engine = (IEngine)Activator.GetObject(typeof(IEngine), "tcp://localhost:1966/Engine");
The object is published with:
RemotingServices.Marshal(this, engineUri);
It does work for single calls at least, but maybe there's threading and release of the IEngine or other issues to consider?
I hope its clear.

If you store the instance of IEngine that was passed to RemotingServices.Marshal then you wouldn't need to call Activator.GetObject from within the service itself as it will be the same instance used by client applications. It will probably need some re-structuring but it would save any calls to IEngine from within your service going over the network stack:
IEngine this.engine = new Engine();
RemotingServices.Marshal(this.engine, engineUri);
// this.engine will be the same instance used by client applications and can also be passed around within your service.

Related

COM Server with only one running instance (Service, Singleton, ...)

for a third party application I need to program a Com Server. This is no problem but I need the COM Server to run only in one instance. This instance should run as a service so that it is not created every time new.
The COM Application is created by vbs every time new.
Dim myCom
Set myCom = Nothing
Set myCom = CreateObject("MyCom.Application")
myCom.DoAction
The Com Server itself creates a database connection and I want to connect once and not for every creation.
I hope you understand what I mean. If not contact me pleade via comment. Thanks.
Chris
Take a look at ExeCOMServer:
ExeCOMServer encapsulates the skeleton of an out-of-process COM server in
C#. The class implements the singleton design pattern and it's thread-safe.
To start the server, call CSExeCOMServer.Instance.Run(). If the server is
running, the function returns directly.

Invoke a method in a Console application that is currently running.

I have a console application I wrote in C# that polls multiple devices, collects some data, and stores the information on a database. The application runs on our web server, and I was wondering how to invoke a method call from the command console (so I can exec a command from php that will be read by the console application, a shell command would work as well).
Anyone got any ideas? I've been floating around 'the google' and have found nothing that will supply my current needs.
Also, i'm not adverse to making changes to the console application if an overhaul is needed there. Please, if your answer is COM Interop, provide a GOOD example of how I would build and call this from PHP / Apache2.
You could create a Service like this:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(
Method = "GET",
UriTemplate = "/magic")]
void MagicMethod();
}
And a service implementation like this:
public class Service : IService
{
public void MagicMethod()
{
//magic here
}
}
to start a HTTP Service it should look like this:
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("http://127.0.0.1:8080"))
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
ServiceDebugBehavior stp = host.Description.Behaviors.Find<ServiceDebugBehavior>();
stp.HttpHelpPageEnabled = false;
host.Open();
This will start a HTTP server on port 8080.
Then you can make a HTTP Get request to 'http://localhost:8080/magic' to invoke the method call.
Perhaps your console app can poll a directory for a certain file, and react to that.
Then your php app will only need to create that file and the console app should notice it and do whatever you want. I'm not really sure what you want to do.
I would look at using WCF. Your C# application would host a WCF service and then your PHP application could call into it, I believe PHP5 comes with a SOAP library which should make this relatively simple. Any other application you write will be able to easily call in to, especially if they're written in .NET.
I imagine COM would work fine, but I like the scalability of WCF, as if you have to end up moving these applications onto separate servers then you wouldn't need to change anything besides a URL.
There's a good example on this blog. If you're using PHP5 it should be a doddle, if you're having to use 4 then it will still be possible but will require just a bit more legwork.

Function call on server by multiple clients: Isolate each client calls

My project was standalone application then I decided to split it as client & server because I need powerful CPU usage and portability at the same time. Now multiple clients can connect to one server.
It was easy when 1 by 1 processing did the job. Now I need to call the same function & scope area again & again at the same time -via client requests-
Please can anyone give me some clue how should I handle these operations, I need to know how can I isolate clients' processes from each other at the server side? My communication is asynchronous, server receives a request and starts a new thread. I think I pass a parameter which one carries the client information, and another parameter as job id -to help client back, client may ask for multiple jobs and some jobs finish quicker than others-
Should I instantiate the class Process on each call? Can I use a static method, etc, any explanation will be of great help!
Below is the part of my code to need modification
class static readonly Data
{
public variable listOfValues[]
}
class Process
{
local variable bestValue
function findBestValue(from, to)
{
...
if(processResult > bestValue) bestValue = processResult
...
}
...
for(i=0;i<10;i++) startThread(findBestValue(i*1000,i*1000+999));
...
}
EDIT: I think I have to instantiate a
new Process class and call the
function for each client and ignore
the same client for same job since job is already running.
Not getting into your application design, since you didn't talk much about it, I think that your problem is ideal for using WCF WebServices. You get client isolation by design because every request will start in it's own thread. You can create WCF host as standalone application/windows service.
You can wrap your communication with WCF service and configure it to be PerCall service (meaning each request will be processed separately from others).
So you'll clean up your buisness logic from syncronization stuff. That's the best way, because managing and creating threads is not difficult to implement, but it is difficult to implement correctly and optimized for resources consumption.

Help me to chose instance management in WCF service

My scenerio is like this:
On the server there is an application which exposes a COM object allowing to interact with this application programaticaly. However I can connect only once through COM due to licence restrictions. So, after initialization a COM object will return me a more specified ConnectionObject.
I need an advice what management model I schould chose for my service which will be interacting with the ConnectionObject:
Per-Call Service:
I have two options here:
I can log through COM, perform operation and Logout releasing the connection. But this logging process is somewhat time consuming.
I could create some sort of
singleton class which could keep
reference to the ConnectionObject.
The problem is that I do not know
how to share the same instance of
object through different instances
of the service? Is it possible?
Singleton Service:
The problem of sharing ConnectionObject does not exists. Object will be created at the begining of life of the service and freed when service will be shut down. However I've read that using this kind of service is not recommended.
Thanks for any advices.
Given your requirements with the COM object, and the time consuming log in and out process - I would go with the singleton service. We use our WCF services like this all the time (also talking to legagy COM objects).
You can add the following attribute to the class definition of your WCF service to get the behaviour:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MyService : IMyServiceContract
{
[OperationBehavior]
public void MyServiceCall ()

.net remoting to invoke Speech Server workflow in non-local application domain

I am implementing a Microsoft Speech Server application built on windows workflow foundation. The app manages other sub apps - users call in and the manager loads the assembly containing the correct application and invokes the workflow.
The problem I'm facing is that speech serve or iis like to lock the assembly into memory, preventing me from overwriting the dll. This makes it a pain to debug the app, but will also be totally unacceptable once the app is deployed to production.
There is no way to manually unload a single specific assembly - assemblies are only unloaded when their parent application domain unloads.
So I am trying to use .net remoting to create a new application domain, load the assembly into that domain, create the workflow object through a proxy, and then I want to pass that proxy around.
This is the code for the type that I am trying to create. It is in the assembly I am trying to load:
public class typeContainer : MarshalByRefObject
{
public static Type workflowType = typeof(mainWorkflow);
}
And here is the code in the manager:
AppDomain newDomain = AppDomain.CreateDomain("newdomain");
System.Runtime.Remoting.ObjectHandle oh = newDomain.CreateInstanceFrom(
#"FullPathToAssembly",
"namespace.typeContainer");
object unwrapped = oh.Unwrap();
So the question is, how can I then access typeContainer.workflowType in the manager? oh.Unwrap() yields a type of _TransparentProxy.
Simply put, what I am trying to do above is impossible. In short, sending a Type across AppDomains results in injecting the assembly into the current domain. For an alternate solution, see this post.

Categories