Hi,
I'm new to .NET remoting and there's something I'm having real trouble with.
Basically, I'd like to create a component that can act as a server and as a
client (can send messages and receive them in asynchronous mode).
Here's the situation just so you guys understand why I'm doing this (and
maybe so that you can provide me with other options):
I have an application that needs to save data to a remote database. The
DBAs don't allow direct modifications or insertions into the database for
security and other reasons. So, they built what we call here an INSERTION
SERVICE (IS). The application that wants to save to the db has to create an
XML file with the details of the changes and drop it on an FTP site for
processing. Problem is that the files can be rejected for many reasons so we
would like to inform the user whether his/her changes have been saved or not.
Since this is a very busy database, the changes are not necessarily done
immediately, the files are put in a priority queue.
So basically, once the changes have been made or not, we need to inform the
user in the App. We thought about building some kind of proxy that resides
between the application and the IS. The application would register itself to
the proxy everytime it sends a new file to the IS. Once the file has been
processed, the IS could send a message to the proxy that would dispatch it to
the App. So, the App would need to act as a client for the original
registration to the proxy and as a server for the reception of the final
message (vice-versa for the proxy).
I tried to create an Interface to derive the client with and then, when a
call is made by the client to the proxy, supply a link to themself (the
client) with the call. Hence, I could then call a procedure on that object
once the work is done.
Here's (snippets of) the code I have written up until now:
<THIS IS THE SHARED OBJECT CODE>
public interface IClient
{
void WorkCompleted(string msg);
}
public class RemoteMessage : MarshalByRefObject
{
public RemoteMessage()
{
ClientQueue = new ArrayList();
}
public void SetClient(string xmlFileName, IClient client)
{
//ClientInfo is a class that stores info on the client and
//a reference to the client (passed with the Interface ref)
ClientQueue.Add(new ClientInfo(xmlFileName, client));
}
public void SetMessage(string xmlFileName, string msg)
{
//Find the corresponding client according to its XML file (unique)
//and return a message through its client interface (asynchonous).
//Finally delete the entry for this client in the collection.
int i;
for (i=ClientQueue.Count-1; i>0; i--)
if (ClientQueue[i].ToString().Equals(xmlFileName))
{
ClientInfo obj = (ClientInfo) ClientQueue[i];
obj.GetClient.WorkCompleted(msg);
ClientQueue.RemoveAt(i);
//Could stop but for debugging purposes, we will continue in case object
is there more than once
}
}
private System.Collections.ArrayList ClientQueue;
}
<THIS IS THE CLIENT CODE>
class Client : IClient
{
RemoteMessage server;
HttpChannel channel;
public Client()
{
Console.WriteLine("***** Client started *****");
Console.WriteLine("Hit ENTER to end.");
}
public void Register()
{
channel = new HttpChannel();
ChannelServices.RegisterChannel(channel);
object remoteObj = Activator.GetObject(
typeof(SI_Remoting.RemoteMessage),
"http://localhost:32469/RemoteServer.soap");
server = (RemoteMessage) remoteObj;
}
public void RegisterNewMsg(string xml)
{
server.SetClient(xml, this);
}
//this will be called by the SI
public void UnregisterMsg(string xml, string msg)
{
server.SetMessage(xml, msg);
}
public void WorkCompleted(string msg)
{
//Return the message sent to DVS.
Console.WriteLine("Received message: {0}", msg);
}
[STAThread]
static void Main(string[] args)
{
Client client = new Client();
client.Register();
client.RegisterNewMsg("xml1");
//client.UnregisterMsg("xml1", "xml has been processed.");
Console.ReadLine();
}
}
I'm having lots of issues with the components I need to serialize and all
the configuration that should be wrapped in there too in order for this to
work. Actually, this code compiles correctly but at run time I get the
following error when I start the client:
Unhandled Exception: System.Runtime.Serialization.SerializationExceptio n:
The type SI_Client.Client in Assembly SI_Client, Version=1.0.1741.22769,
Culture=neutral, PublicKeyToken=null is not marked as serializable.
I don't know what to do next (because I don't want to start putting
[Serializable] tags everywhere or other stuff until it works, I want to
understand what I do).
Thanks a lot in advance for all your help,
Skip.