Services|web
- Decoding and de-serializing of the request message
- Invoking the Remote method
- Encoding and serialization of the response message
[WebMethod]
public string SyncProcessMessage (string request)
{
//request:decoding and deserializing
byte[] Reqbytearray = convert.frombase64string (request);
MemoryStream reqstream = new MemoryStream ();
Reqstream. Write (Reqbytearray, 0, reqbytearray.length);
Reqstream. Position = 0;
BinaryFormatter bf = new BinaryFormatter ();
IMessage reqmsg = (IMessage) bf. Deserialize (Reqstream);
Reqmsg. properties["__uri"] = reqmsg. properties["__uri2"];
//Work around!!
Reqstream. Close ();
//Action:invoke the Remote method
string[] stype = reqmsg. properties["__typename"]. ToString (). Split (New char[]{', '});
//Split TypeName
Assembly asm = Assembly.Load (stype[1). TrimStart (New char[]{'}));
//load type of the remote object
Type ObjectType = asm. GetType (Stype[0]);
//Type
String objecturl = Reqmsg. properties["__uri"]. ToString ();
//Endpoint
Object ro = Remotingservices.connect (ObjectType, Objecturl);
//Create proxy
Traceimessage (REQMSG);
IMessage rspmsg = remotingservices.executemessage (MarshalByRefObject) RO,
(IMethodCallMessage) reqmsg);
Traceimessage (RSPMSG);
//response:encoding and serializing
MemoryStream rspstream = new MemoryStream ();
Bf. Serialize (Rspstream, rspmsg);
Rspstream. Position = 0;
String response = Convert.tobase64string (Rspstream. ToArray ());
Rspstream. Close ();
return response;
}
[WebMethod]
public string Syncprocesssoapmessage (string request)
{
IMessage retmsg = null;
string response;
Try
{
Trace.WriteLine (Request);
///Request:deserialize string into the SoapMessage
SoapFormatter SF = new SoapFormatter ();
sf. Topobject = new SoapMessage ();
StreamWriter rspsw = new StreamWriter (new MemoryStream ());
RSPSW. Write (Request);
RSPSW. Flush ();
RSPSW. basestream.position = 0;
Isoapmessage soapmsg = (isoapmessage) sf. Deserialize (RSPSW. BaseStream);
RSPSW. Close ();
//Action:invoke the Remote method
Object[] values = soapmsg. Paramvalues;
string[] stype = values[2]. ToString (). Split (New char[]{', '});
Assembly asm = Assembly.Load (stype[1). TrimStart (New char[]{'}));
Type ObjectType = asm. GetType (Stype[0]);
String objecturl = Values[0]. ToString ();
Realproxywrapper RPW = new Realproxywrapper (ObjectType, Objecturl,
Soapmsg. PARAMVALUES[4]);
Object ro = rpw. Gettransparentproxy ();
MethodInfo mi = Objecttype.getmethod (values[1]. ToString ());
Object retval = mi. Invoke (RO, values[3] as object[]);
Retmsg = RPW. ReturnMessage;
}
catch (Exception ex)
{
retmsg = new ReturnMessage (ex. innerexception = null)?
Ex:ex. InnerException, NULL);
}
Finally
{
//Response:serialize IMessage into string
Stream Rspstream = new MemoryStream ();
SoapFormatter SF = new SoapFormatter ();
Remotingsurrogateselector RSS = new Remotingsurrogateselector ();
Rss. Setrootobject (RETMSG);
sf. SurrogateSelector = RSS;
sf. Assemblyformat = Formatterassemblystyle.full;
sf. Typeformat = Formattertypestyle.typesalways;
sf. Topobject = new SoapMessage ();
sf. Serialize (Rspstream, retmsg);
Rspstream. Position = 0;
StreamReader sr = new StreamReader (rspstream);
Response = Sr. ReadToEnd ();
Rspstream. Close ();
Sr. Close ();
}
Trace.WriteLine (response);
return response;
}
The implementation of the steps are depended from the type of formatter such as SoapFormatter or BinaryFormatter. The steps are straightforward using the Remoting namespace classes. The second one (action) for the "SoapFormatter message needed to create" following class to obtain IMessage of the Metho Dcall:
public class Realproxywrapper:realproxy
{
String _url;
String _objecturi;
IMessageSink _messagesink;
IMessage _MSGRSP;
LogicalCallContext _LCC;
Public IMessage ReturnMessage {get {return _MSGRSP}}
Public Realproxywrapper (type type, string URL, Object LCC): Base (Type)
{
_url = URL;
_LCC = LCC as LogicalCallContext;
foreach (IChannel channel in Channelservices.registeredchannels)
{
If (channel is IChannelSender)
{
IChannelSender Channelsender = (IChannelSender) channel;
_messagesink = Channelsender.createmessagesink (_url, NULL, out _objecturi);
if (_messagesink!= null)
Break
}
}
if (_messagesink = null)
{
throw new Exception ("A supported channel could not being found for URL:" + _url);
}
}
public override IMessage Invoke (IMessage msg)
{
Msg. properties["__uri"] = _url;
//Endpoint
Msg. properties["__CallContext"] = _LCC;
//Caller ' s CallContext
_MSGRSP = _messagesink.syncprocessmessage (msg);
return _MSGRSP;
}
}
//Realproxywrapper
Test
I built the following package to test functionality of the Webservicelistener and Webservicechannellib. This is package has only test purpose. Here are what you downloaded it:
- consoleclient, the test console program to invoke the call over Internet-client machine
- Consoleserver, the host process of the Myremoteobject-server machine
- Myremoteobject, the remote Object-server machine
- Webservicechannellib, the custom client channel
- Webservicelistener, the Web Service listener-server machine
To recompile a package and their deploying in your environment the following notes:
- The folder Webservicelistener has to is moved to the virtual directory (Inetpub\Wwwroot).
- The myremoteobject Assembly has to is install into the GAC on the server machine
- The webservicechannellib Assembly has to is install into the GAC on the client machine
- (option) The msmqchannellib Assembly [1] has to is install into the GAC on the server machine
- The solution can be tested also using the same machine (Win2k/adv Server)
- Use the " Echo " WebMethod on the test page of the " Webservicelistener to be sure" this service would be W Ork
The test case was very simple. The launch the
ConsoleserverProgram. Secondly Open the
consoleclientprogram and follow its prompt text. If Everything is going right you'll have a response from the remote object over the Internet. I am recommending to make a, the same machine and then deploying over the Internet.
Conclusion
In this article has been shown one simple way the how to implement a solution for remoting over the Internet. I used the power of. Net technologies such as SOAP, Remoting, Reflection and Web Service. The advantage of this solution are a full transparency between the consumer and remote object. This logical connectivity can is mapped into the physical path using the config files and which they can be administratively Changed.