|
//======================================================================================================
// The Web service IMessage/SoapMessage Gateway.
// (C) Copyright 2002, Roman Kiss (rkiss@pathcom.com)
// All rights reserved.
// The code and information is provided "as-is" without waranty of any kind, either expresed or implied.
//------------------------------------------------------------------------------------------------------
// History:
// 22-01-2002 RK Initial Release
//======================================================================================================
//
using System;
using System.Threading;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.Xml.Serialization;
using System.Text;
using System.IO;
//
using System.Reflection;
using System.Messaging;
//
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Channels;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
namespace RKiss.WebServiceListener
{
[Serializable]
public class User : ILogicalThreadAffinative
{
private string FirstName;
private string LastName;
public string lastname{ get{ return LastName; } set{LastName = value;}
}
public string firstname{ get{ return FirstName; } set{FirstName = value;}
}
}
public class Service : System.Web.Services.WebService
{
public Service()
{
//CODEGEN: This call is required by the ASP.NET Web Services Designer
InitializeComponent();
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}
#endregion
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
}
[WebMethod]
public string Echo(string msg)
{
return string.Format("{0}, {1}", DateTime.Now, msg);
}
[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 Methode
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 Methode
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;
}
// helper
private void TraceIMessage(IMessage msg)
{
try
{
if(msg is IMethodCallMessage)
Trace.WriteLine("IMethodCallMessage");
if(msg is IMethodReturnMessage)
Trace.WriteLine("IMethodReturnMessage");
Trace.WriteLine(string.Format(" Message Type: {0}", msg.GetType().FullName));
Trace.WriteLine(" Message Properties:");
IDictionary d = msg.Properties;
IDictionaryEnumerator e = (IDictionaryEnumerator) d.GetEnumerator();
while(e.MoveNext())
{
object val = e.Value;
object key = e.Key;
string keyName = key.ToString();
Trace.WriteLine(string.Format(" {0} : {1}", keyName, val));
if((keyName == "__Args") ||
(keyName == "__OutArgs") ||
((keyName == "__MethodSignature") && (null != val)))
{
int ii = 0;
foreach(object arg in val as object[])
{
if(arg == null)
Trace.WriteLine(string.Format(" arg[{0}] = null", ii++));
else
Trace.WriteLine(string.Format(" arg[{0}] = {1}, {2}", ii++, arg, arg.GetType()));
}
}
if((keyName == "__CallContext") && (null != val))
{
LogicalCallContext logicallContext = (LogicalCallContext)val;
// retrieve a Call ID into the CallContext
object cid = logicallContext.GetData("__CallID");
if(null != cid)
{
Trace.WriteLine(string.Format(" __CallID: {0}", cid.ToString()));
}
}
}
}
catch(Exception ex)
{
Trace.WriteLine(ex.Message);
}
}
}//Service
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 be 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
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.