Benutzer mit den meisten Antworten
Probleme mit der Kommunikation zwischen 2 Prozessen auf einem Recher.

Frage
-
Hallo NG,
ich habe ein Programm welches im Vordergrund arbeitet und eines welches als Programm starten und dem Programm Befehle übergeben.
Dazu habe ich folgenden Code erstellt.
Ich habe für den Server folgende Kontrakte:
[ServiceContract] public interface IServerContract { [OperationContract(IsOneWay = true)] void Down(); }
für den Client:
[ServiceContract] public interface IClientContract { [OperationContract(IsOneWay = true)] void Down(); [OperationContract(IsOneWay = true)] void SendSeriesEmails(); }
Der Servercode:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.Single)] public sealed class Server : IServerContract { private enum ClientCalls { Down, SendSeriesEmails, } private readonly Guid sessionGuid = Guid.NewGuid(); private readonly string helpFileName; private ServiceHost _serverHost; public Server(Form mainForm, string helpFileName) { this.helpFileName = helpFileName; mainForm.FormClosed += mainForm_FormClosed; StartProgramm(); } public bool IsClientRunning { get;private set; } private bool NoShowException { get; set; } private void mainForm_FormClosed(object sender, EventArgs e) { Down(); } public void StartServer() { _serverHost = new ServiceHost(this); _serverHost.AddServiceEndpoint((typeof(IServerContract)), new NetNamedPipeBinding(), "net.pipe://localhost/EMailServer_" + sessionGuid); _serverHost.Open(); } public EventHandler ClientDown; public void Down() { CallToClient(ClientCalls.Down); } public void SendSeriesEmails() { CallToClient(ClientCalls.SendSeriesEmails); } private void CallToClient(ClientCalls call) { if (!IsClientRunning) return; using (ChannelFactory<IClientContract> factory = new ChannelFactory<IClientContract>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/EMailServer_" + sessionGuid))) { IClientContract serverToClientChannel = factory.CreateChannel(); try { switch (call) { case ClientCalls.Down: NoShowException = true; serverToClientChannel.Down(); break; case ClientCalls.SendSeriesEmails: serverToClientChannel.SendSeriesEmails(); break; default: throw new ArgumentOutOfRangeException("Manthey.EMail.Communication.Server.CallToClient:call", call.ToString()); } } catch (EndpointNotFoundException) { } catch (Exception ex) { StdMessages.ShowException(ex); } finally { CloseChannel((ICommunicationObject)serverToClientChannel); NoShowException = false; } } } private void CloseChannel(ICommunicationObject channel) { try { channel.Close(); } catch (CommunicationObjectFaultedException) { } catch (Exception ex) { if (!NoShowException) StdMessages.ShowException(ex); } finally { channel.Abort(); } } /// <summary> /// Startet das Server Programm /// </summary> private void StartProgramm() { string fileName = Path.Combine(@"C:\Users\Ingo\Documents\Visual Studio 2012\Projects\Manthey2\EMailSvr\bin\Debug", "EMailSvr.exe"); try { ProcessStartInfo startInfo = new ProcessStartInfo(fileName) { Arguments = String.Format("\"{0}\" \"{1}\"", helpFileName, sessionGuid), UseShellExecute = true, WindowStyle = ProcessWindowStyle.Hidden }; Process.Start(startInfo).WaitForInputIdle(); IsClientRunning = true; } catch (Exception ex) { StdMessages.ShowException(ex); } } void IServerContract.Down() { IsClientRunning = false; if (ClientDown != null) ClientDown(this, EventArgs.Empty); } public bool ServerNotExist {get; private set;} }
Für den Client:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.Single)] public sealed class Client : IClientContract { private enum ServerCalls { Down, } private readonly Guid sessionGuid; private ServiceHost _clientHost; public Client(Form mainForm, Guid sessionGuid) { this.sessionGuid = sessionGuid; mainForm.FormClosed += mainForm_FormClosed; } private void mainForm_FormClosed(object sender, EventArgs e) { Down(); } public void Down() { CallToServer(ServerCalls.Down); } public bool IsServerRunning { get; private set; } private bool NoShowException { get; set; } private void CallToServer(ServerCalls call) { if (!IsServerRunning) return; using (ChannelFactory<IServerContract> factory = new ChannelFactory<IServerContract>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/EMailClient_" + sessionGuid))) { IServerContract clientToServerChannel = factory.CreateChannel(); try { switch (call) { case ServerCalls.Down: NoShowException = true; clientToServerChannel.Down(); break; break; default: throw new ArgumentOutOfRangeException("Manthey.EMail.Communication.Client.CallToServer:call", call.ToString()); } } catch (EndpointNotFoundException) { } catch (Exception ex) { StdMessages.ShowException(ex); } finally { CloseChannel((ICommunicationObject)clientToServerChannel); NoShowException = false; } } } private void CloseChannel(ICommunicationObject channel) { try { channel.Close(); } catch (CommunicationObjectFaultedException) { } catch (Exception ex) { if (!NoShowException) StdMessages.ShowException(ex); } finally { channel.Abort(); } } public void StartClient() { _clientHost = new ServiceHost(this); _clientHost.AddServiceEndpoint((typeof(IClientContract)), new NetNamedPipeBinding(), "net.pipe://localhost/EMailClient_" + sessionGuid); _clientHost.Open(); } public EventHandler ServerDown; public EventHandler SendSerialEmails; void IClientContract.Down() { IsServerRunning = false; if (ServerDown != null) ServerDown(this, EventArgs.Empty); } void IClientContract.SendSeriesEmails() { if (SendSerialEmails != null) SendSerialEmails(this, EventArgs.Empty); } }
Nun habe ich folgende Exception bekommen:
Der Kanal hat beim Schließen eine unerwartete Fehlereingabenachricht empfangen. Angegebene Fehlerursache: "Die Nachricht mit Action "http://tempuri.org/IClientContract/SendSeriesEmails" kann aufgrund einer fehlenden ContractFilter-Übereinstimmung beim EndpointDispatcher nicht verarbeitet werden. Mögliche Ursachen: Vertragskonflikt (keine Action-Übereinstimmung zwischen Sender und Empfänger) oder ein Bindung/Sicherheit-Konflikt zwischen dem Sender und dem Empfänger. Stellen Sie sicher, dass Sender und Empfänger über den gleichen Vertrag und die gleiche Bindung verfügen (einschließlich Sicherheitsanforderungen, z. B. "Message", "Transport", "None")."
Leider sehe ich meinen Fehler nicht. Was mache ich falsch??
Danke im voraus für jeden Hinweis und Tipp.
Mir ist auch jeder andere Weg um einen anderen Prozess zu informieren lieb.
Grüße Ingo
Antworten
-
Hallo,
Ich glaube du hast nur etwas verwechselt: In deiner CallToClient-Prozedur muss als Endpoint natürlich die Adresse des Clients stehen, du hast EMailServer dastehen.
Umgekehrt musst du in deiner Client-Klasse beim CallToServer natürlich die Adresse des Servers angeben ;-)
Gruß
- Als Antwort markiert IngoManthey Freitag, 2. Mai 2014 10:42
Alle Antworten
-
Hallo,
Ich glaube du hast nur etwas verwechselt: In deiner CallToClient-Prozedur muss als Endpoint natürlich die Adresse des Clients stehen, du hast EMailServer dastehen.
Umgekehrt musst du in deiner Client-Klasse beim CallToServer natürlich die Adresse des Servers angeben ;-)
Gruß
- Als Antwort markiert IngoManthey Freitag, 2. Mai 2014 10:42