DDE-Server in WebService integrieren

slang

Grünschnabel
Hallo Forum,

ich muss eine Middleware für einen SOAP-Server/Client und einen DDE-Server/Client schreiben, damit die beiden sich bidirektional unterhalten können. Ich hätte das ganze gerne in einen WebService integriert, stoße dabei aber auf folgenden Fehler:

Der DDE-Server (alle anderen Komponenten laufen) scheint zwar problemlos zu starten, wenn ich diesen aber versuche anzusprechen, bekommt der Client keine Verbindung und der Server wirft folgenden Fehler: A first chance exception of type 'System.InvalidOperationException' occurred in NDde.DLL. Für den DDE-Server benutze ich die NDde.dll, habe den gleichen Server auch schon in einer "normalen" Windows Forms Applikation getestet, da funktioniert er einwandfrei.

Nun meine Frage: hat irgend jemand eine Ahnung wieso der DDE-Server unter dem WebService nicht läuft?

Anbei noch der Code des WebService und des DDE-Servers.

Code:
public class Middleware : System.Web.Services.WebService
    {
        private static DDEServer ddeServer = null;

        [WebMethod]
        public bool Initialize(string test)
        {
            try
            {
                ddeServer = new DDEServer("Middleware");
            }
            catch
            {
                return false;
            }

            return true;
        }

        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";        
        }
}

Der DDE-Server:
Code:
/// <summary>
    /// 
    /// </summary>
    class DDEServer : DdeServer
    {
        private Timer timer = new Timer();

        public DDEServer(string service) : base(service)
        {
            // Create a timer that will be used to advise clients of new data.
            timer.Elapsed += this.OnTimerElapsed;
            timer.Interval = 1000;
            timer.SynchronizingObject = this.Context;
            timer.Start();
        }        

        private void OnTimerElapsed(object sender, ElapsedEventArgs args)
        {
            // Advise all topic name and item name pairs.
            Advise("*", "*");
        }

        protected override bool OnBeforeConnect(string topic)
        {
            Console.WriteLine("OnBeforeConnect:".PadRight(16)
                + " Service='" + base.Service + "'"
                + " Topic='" + topic + "'");

            return true;
        }

        protected override void OnAfterConnect(DdeConversation conversation)
        {
            Console.WriteLine("OnAfterConnect:".PadRight(16)
                + " Service='" + conversation.Service + "'"
                + " Topic='" + conversation.Topic + "'"
                + " Handle=" + conversation.Handle.ToString());
        }

        protected override void OnDisconnect(DdeConversation conversation)
        {
            Console.WriteLine("OnDisconnect:".PadRight(16)
                + " Service='" + conversation.Service + "'"
                + " Topic='" + conversation.Topic + "'"
                + " Handle=" + conversation.Handle.ToString());
        }

        protected override bool OnStartAdvise(DdeConversation conversation, string item, int format)
        {
            Console.WriteLine("OnStartAdvise:".PadRight(16)
                + " Service='" + conversation.Service + "'"
                + " Topic='" + conversation.Topic + "'"
                + " Handle=" + conversation.Handle.ToString()
                + " Item='" + item + "'"
                + " Format=" + format.ToString());

            // Initiate the advisory loop only if the format is CF_TEXT.
            return format == 1;
        }

        protected override void OnStopAdvise(DdeConversation conversation, string item)
        {
            Console.WriteLine("OnStopAdvise:".PadRight(16)
                + " Service='" + conversation.Service + "'"
                + " Topic='" + conversation.Topic + "'"
                + " Handle=" + conversation.Handle.ToString()
                + " Item='" + item + "'");
        }

        protected override ExecuteResult OnExecute(DdeConversation conversation, string command)
        {
            Console.WriteLine("OnExecute:".PadRight(16)
                + " Service='" + conversation.Service + "'"
                + " Topic='" + conversation.Topic + "'"
                + " Handle=" + conversation.Handle.ToString()
                + " Command='" + command + "'");

            // Tell the client that the command was processed.
            return ExecuteResult.Processed;
        }

        protected override PokeResult OnPoke(DdeConversation conversation, string item, byte[] data, int format)
        {
            Console.WriteLine("OnPoke:".PadRight(16)
                + " Service='" + conversation.Service + "'"
                + " Topic='" + conversation.Topic + "'"
                + " Handle=" + conversation.Handle.ToString()
                + " Item='" + item + "'"
                + " Data=" + data.Length.ToString()
                + " Format=" + format.ToString());

            // Tell the client that the data was processed.
            return PokeResult.Processed;
        }

        protected override RequestResult OnRequest(DdeConversation conversation, string item, int format)
        {
            Console.WriteLine("OnRequest:".PadRight(16)
                + " Service='" + conversation.Service + "'"
                + " Topic='" + conversation.Topic + "'"
                + " Handle=" + conversation.Handle.ToString()
                + " Item='" + item + "'"
                + " Format=" + format.ToString());

            // Return data to the client only if the format is CF_TEXT.
            if (format == 1)
            {
                return new RequestResult(System.Text.Encoding.ASCII.GetBytes("Time=" + DateTime.Now.ToString() + "\0"));
            }
            return RequestResult.NotProcessed;
        }

        protected override byte[] OnAdvise(string topic, string item, int format)
        {
            Console.WriteLine("OnAdvise:".PadRight(16)
                + " Service='" + this.Service + "'"
                + " Topic='" + topic + "'"
                + " Item='" + item + "'"
                + " Format=" + format.ToString());

            // Send data to the client only if the format is CF_TEXT.
            if (format == 1)
            {
                return System.Text.Encoding.ASCII.GetBytes("Time=" + DateTime.Now.ToString() + "\0");
            }
            return null;
        }
          
    } // class
 
Servus,

hab wohl selbst eine Erklärung gefunden. DDE basiert auf der Windows API Funktion SendMessage und diese braucht ein Window Handle. Bei einem WebService gibt es (natürlich) kein Window Handle. Falls ich falsch liege, bitte darauf hinweisen.

Ciao
 
:mad:

Alles d%"m Geschwätz! Man darf nur nicht vergessen den DDE-Server zu registrieren, dann läuft er auch unter einem WebService.
 
Zurück