Frage

Ich bin der Gestaltung eines Client-Server-Chat-Anwendung (in der Tat bin ich nicht, aber lassen Sie uns so tun, ich bin :)), und ich bin ein bisschen von einigen Rennbedingungen verwirrt ich erlebt habe.

Lassen Sie uns sagen, ich habe den folgenden Code bekommen:

public interface IServer
{
  [OperationContract(IsOneWay = false)]
  [FaultContract(typeof(ChatException))]
  void BroadcastMessage(string msg);
}

public class Server : IServer 
{
  void BroadcastMessage(string msg) // I'm not mentionning the try/catch/throw FaultException here for readability purposes
  {
    foreach (IClientCallback c in callbacks){
      c.ReceiveMessage(msg);
    }

  }
}

public interface IClientCallback
{
  [OperationContract(IsOneWay = true)]
  void ReceiveMessage(string s);
}

Und hier ist ein Auszug aus der Bindungskonfiguration:

<endpoint address="" 
binding="netTcpBinding" 
bindingConfiguration="DuplexBinding" 
contract="IServer" />

 <binding name="DuplexBinding" sendTimeout="00:01:00">
   <reliableSession ordered="true" inactivityTimeout="00:05:00" enabled="true"/>
   <security mode="None">
     <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
     <message clientCredentialType="Windows" />
   </security>
 </binding>

Das ist natürlich eine Art von Pseudo-c #, ich habe eine Menge von nicht-relevantem Code aus Gründen der Übersichtlichkeit halber entfernt.

Jetzt auf den Punkt: Dieser Code wird nicht funktionieren. Als ich Broadcast nennen, nie die Methode gibt, und ich schließlich einen Timeout auf der Client-Seite. Wenn ich auf der Server-Seite zu debuggen, alles scheint in Ordnung (ich aus dem Broadcast Methode gibt genau so, wie man erwarten würde, und ich bin blockiert nicht auf irgendwelchen ReceiveMessage eine Möglichkeit, Anrufe)

Hier sind zwei Möglichkeiten, diesen Code zu beheben:

  1. die FaultContract entfernen und die Broadcast Methode als oneway = true
  2. erklären
  3. Broadcastübertragung die Nachricht an alle aber die anfängliche Absender

Meine erste Vermutung war, dass die Client-Seite wartet auf den Server zurück, und damit war für die Handhabung des eingehenden ReceiveMessage Anrufs vom Server nicht verfügbar, wodurch den Server blockiert, ABER ReceiveMessage als oneway erklärt, und das Debuggen der Server zeigt, dass es nicht auf jeden Aufruf ReceiveMessage blockiert

Nun meine Fragen:

  • Was ist los?

  • Gibt es andere Möglichkeiten, dies zu beheben? (Vielleicht durch die Bindung Konfiguration Tuning?)

  • Lassen Sie uns sagen, dass ich fix wählen 2 (dh nicht an den Absender zurück gesendet), was passiert, wenn der Server geschieht meine ReceiveMessage Rückrufe (weil jemand anderes mir eine Nachricht geschickt), während ich für meine eigene Warte bin Broadcast rufen zu beenden?

  • Ich habe gelesen, dass OneWay Anrufe sind nicht völlig oneway, und dass der Server wartet noch auf eine HTTP-Antwort von der anderen Seite. Sämtliche Angaben dazu? Insbesondere ist der Kunde in der Lage suchte HTTP-Antworten zu reagieren, wenn es in einem entfernten Anruf blockiert wird?

Edit: Console .net 3.5 auf der Server-Seite, WinForms .net 3.5 auf der Client-Seite

War es hilfreich?

Lösung

Es klingt wie eine Sackgasse, vielleicht aufgrund des Sync-Kontext. Was ist der Kunde? Winform? WPF? WCF respektiert sync-Kontext, der „-Schalter auf dem UI-Thread“ für WinForms und WPF bedeutet. Wenn Sie machen die Sperranforderung auf dem UI-Thread, dann Spiel vorbei.

Versuchen Sie WCF Anfrage auf einem Hintergrund-Thread durchgeführt wird, so dass der UI-Thread verfügbar ist, um die eingehende Anfrage zu bedienen; Dies könnte so einfach wie mit ThreadPool sein, oder vielleicht BackgroundWorker.

Andere Tipps

Versuchen Sie, dieses Attribut auf Ihre konkrete Umsetzung Ihres Service:

[System.ServiceModel.ServiceBehavior(UseSynchronizationContext=false)]
public class Server : IServer {}

Zweitens, versuchen Sie auf WCF drehen Tracing, um zu sehen, wenn Sie etwas passiert in den Därmen Ihrer WCF Implementierung haben, die Ihre Trauer gibt. Ich habe einige wirklich seltsame Fehler hatte, die nur Sinn, wenn ich in Verfolgung ging hin und fand die eigentliche Fehlermeldung aus, das wurde auftritt.

ein WCF-Dienst Tracing

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top