Announcement

Collapse
No announcement yet.

WCF Client Anmeldung/Abmeldung einstellen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • WCF Client Anmeldung/Abmeldung einstellen

    Hallo Zusammen,

    ich habe eine Client-Server - Anwendung mit WCF programmiert. Funktioniert prima, bis auf einen Timeout.

    Problem:
    Ich starte ein Fenster, die erforderlichen Daten werden vom Server abgeholt. Allerdings wird die Client-Verbindung nach dem erhalten der Daten nach ein paar Sekunden abgebrochen. Hier ein Auszug aus meiner Log-Datei:

    19.07.2012 11:43:55 - ===>>> Klasse : DataAcquisition
    Methode: public void Subscribe()
    Ein Client wurde angemeldet!
    19.07.2012 11:43:55 - ===>>> Klasse : DataAcquisition.cs
    Methode: public ConnectionErrorColor Connect()
    Returnwert: Ready
    19.07.2012 11:43:55 - ===>>> Klasse : DataAcquisition.cs
    Methode: public bool CheckUserName(string userName)
    Returnwert: True
    19.07.2012 11:43:55 - ===>>> Klasse : DataAcquisition.cs
    Methode: public int GetUserId(string userName)
    Returnwert: 1
    19.07.2012 11:43:55 - ===>>> Klasse : DataAcquisition.cs
    Methode: public string GetPwd(int userID)
    Returnwert: 1156371652
    19.07.2012 11:43:59 - ===>>> Klasse : DataAcquisition
    Methode: public void Subscribe()
    Ein Client wird geschlossen....
    19.07.2012 11:43:59 - ===>>> Klasse : DataAcquisition
    Methode: public void Subscribe()
    Ein Client wurde abgemeldet!


    Nach ca. vier Sekunden wird er automatisch abgemeldet.

    Ich bekomme es einfach nicht hin, dass die Verbindung so lange anhält, wie ich mich gerade im Bearbeitungsfenster befinde. Sobald ich eine Änderung durchführe, baut sich die Verbindung auf und schließt dann wieder.

    Hier meine app.config - Server
    [highlight=xml]
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <system.serviceModel>
    <bindings>
    <netTcpBinding>
    <binding name="NetTcpBinding_IEventSystem"
    closeTimeout="00:01:00"
    openTimeout="00:01:00"
    receiveTimeout="00:10:00"
    sendTimeout="00:01:00"
    maxConnections="100">
    <security mode="None"></security>
    </binding>
    </netTcpBinding>
    </bindings>
    <behaviors>
    <serviceBehaviors>
    <behavior name="ExposeMexAndThrottleBehavior">
    <serviceMetadata/>
    <serviceThrottling maxConcurrentCalls="100" maxConcurrentInstances="101" maxConcurrentSessions="101"/>
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <services>
    <service name="AmpelfunktionCCCServer.Globals.DataAcquisiti on" behaviorConfiguration="ExposeMexAndThrottleBehavio r">
    <endpoint
    address="net.tcp://alo-win7:9400/DataAcquisition/"
    binding="netTcpBinding"
    contract="AmpelfunktionCCCServer.Interfaces.IDataA cquisition"
    bindingConfiguration="NetTcpBinding_IEventSystem"/>
    <endpoint
    address="net.tcp://alo-win7:9401/DataAcquisition/Mex"
    binding="mexTcpBinding"
    contract="IMetadataExchange">
    </endpoint>
    </service>
    </services>
    </system.serviceModel>
    </configuration>
    [/highlight]
    Hier meine app.config - Client
    [highlight=xml]
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <system.serviceModel>
    <bindings>
    <netTcpBinding>
    <binding name="NetTcpBinding_IEventSystem"
    closeTimeout="00:01:00"
    openTimeout="00:01:00"
    receiveTimeout="00:10:00"
    sendTimeout="00:01:00"
    >
    <security mode="None"></security>
    </binding>
    </netTcpBinding>
    </bindings>
    <client>
    <endpoint address="net.tcp://alo-win7:9400/DataAcquisition/"
    binding="netTcpBinding"
    bindingConfiguration="NetTcpBinding_IEventSystem"
    contract="Interfaces.IDataAcquisition"
    name="NetTcpBinding_IEventSystem">
    <identity>
    <dns value="localhost" />
    </identity>
    </endpoint>
    </client>
    </system.serviceModel>
    [/highlight]

    Was kann ich unternehmen, dass die Verbindung erst unterbrochen wird wenn ich es möchte?

    Vielen Dank für Eure Unterstützung.

    Gruß Lerando

  • #2
    Hallo,

    verwendest du Sessions? Wenn nicht ist es normal, dass die Verbindung wieder geschlossen wird.

    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Vielen Dank für den Hinweis.

      Mein Server-Interface:
      [highlight=csharp]
      [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IEventSystemCallback))]
      public interface IDataAcquisition
      {
      [OperationContract(IsOneWay = false)]
      ConnectionErrorColor Connect();
      [OperationContract(IsOneWay = false)]
      void Disconnect();
      [OperationContract(IsOneWay = true)]
      void Subscribe();

      [OperationContract(IsOneWay = true)]
      void Unsubscribe();
      [OperationContract(IsOneWay = false)]
      List<String> GetUserList();
      [OperationContract(IsOneWay = false)]
      String GetUser();
      [OperationContract(IsOneWay = false)]
      Int32 GetUserId(String userName);
      [OperationContract(IsOneWay = false)]
      String GetPwd(int userID);
      [OperationContract(IsOneWay = false)]
      String GetRolle(int userID);

      [OperationContract(IsOneWay = false)]
      Boolean CheckUserName(String userName);

      [OperationContract(IsOneWay = false)]
      Boolean SetUser(string userName, int userId);

      [OperationContract(IsOneWay = false)]
      Boolean SetNewUser(string userName, string userPwd, int userRolle);

      [OperationContract(IsOneWay = false)]
      Boolean SetPwd(string pwd, int userId);

      [OperationContract(IsOneWay = false)]
      Boolean SetRolle(Int32 rolle, int userId);

      [OperationContract(IsOneWay = false)]
      Boolean DeleteUser(Int32 userID);
      }
      [/highlight]
      Meine Server-Ausführende Datei (Auszug)
      [highlight=csharp]
      [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
      public class DataAcquisition : IDataAcquisition
      {
      public delegate void CallbackDelegate<T>(T t);
      public static CallbackDelegate<string> MessageReceived;
      ....
      public static DataAcquisition DataAcquisitionSingleton;

      public DataAcquisition()
      {
      if (DataAcquisitionSingleton == null)
      {
      DataAcquisitionSingleton = this;
      }
      }
      ....
      [/highlight]
      Mein Client-Interface:
      [highlight=csharp]
      [ServiceContractAttribute(ConfigurationName = "Interfaces.IDataAcquisition", CallbackContract = typeof(IEventSystemCallback), SessionMode = SessionMode.Required)]
      public interface IDataAcquisition
      {
      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/Connect")]
      ConnectionErrorColor Connect();
      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/Disconnect")]
      void Disconnect();

      [OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IDataAcquisition/Subscribe")]
      void Subscribe();

      [OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IDataAcquisition/Unsubscribe")]
      void Unsubscribe();
      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/GetUser")]
      String GetUser();
      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/GetUserId")]
      Int32 GetUserId(String userName);
      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/GetPwd")]
      String GetPwd(int userID);
      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/GetRolle")]
      String GetRolle(int userID);

      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/CheckUserName")]
      Boolean CheckUserName(String userName);

      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/SetUser")]
      Boolean SetUser(string userName, int userId);

      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/SetNewUser")]
      Boolean SetNewUser(string userName, string userPwd, int userRolle);

      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/SetPwd")]
      Boolean SetPwd(string pwd, int userId);

      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/SetRolle")]
      Boolean SetRolle(Int32 rolle, int userId);

      [OperationContractAttribute(IsOneWay = false, Action = "http://tempuri.org/IDataAcquisition/DeleteUser")]
      Boolean DeleteUser(Int32 userID);
      }
      [/highlight]
      Da ich nur ein WCF-Beispiel aus dem Internet verwende aber selber nicht gerade die Ahnung von WCF habe, denke ich doch, dass Ich eine Session habe.

      Allerdings ist mir aufgefallen, dass ich den Aufruf und die Beantwortung in verschiedenen Klassen habe. Kann es sein, dass ich hier eine Klassenübergreifende Lösung finden sollte?
      Zuletzt editiert von Lerando; 19.07.2012, 15:04.

      Comment


      • #4
        Hallo,

        was IsOneWay bewirkt bzw. bedeutet ist dir klar? Ich vermute dass davon das Problem ausgeht.

        aber selber nicht gerade die Ahnung von WCF habe
        Das solltest du umgehend ändern, sonst werden noch einige weitere Probleme auf dich zu kommen (können). Schau dir auch Using Sessions an.

        mfG Gü
        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

        Comment


        • #5
          Vielen Dank für die Info.

          Was ich weiß, ist dass der IsOneWay=true, nur eine Verbindungsrichtung eingeht, so wurde es mir gesagt. Ich werde natürlich Deine Seite sorgfältig durchlesen.

          Im Anhang ist das Beispiel, dass mir als Vorlage diente. Hier ist es aber genau so.

          Was könnte denn an meiner Umsetzung für das Real-Programm falsch sein?

          ESBServiceNeu --> muss mit Administratorrechten ausgeführt werden

          Gruß Lerando

          Mir fällt noch ein, dass ich beim Start die Klasse Instanziiere und dann an die anderen Klassen weitergebe, vielleicht liegt hier der Hund begraben.

          Hier ein Ausschnitt aus dem Real-Code
          [highlight=csharp]
          public partial class App : Application
          {
          #region Variablen - Menüleiste
          private Tray _tray;
          private Icon _icon;
          private Uri _uri;
          private string _schwelleZeitdauer;
          private int _schwelleAnzahl;
          #endregion

          #region Variablen - Views
          private Dashboard _dashboard = new Dashboard();
          private ListenerGetData _listenerGetData;
          private Login _login;
          private InformationsFenster informationsFenster = new InformationsFenster();
          #endregion

          #region Variablen - Events
          private EventServerDaten _eventServerDaten;
          #endregion

          #region Tray
          TrayColors _trayColors;
          #endregion

          protected override void OnStartup(StartupEventArgs e)
          {
          this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
          _listenerGetData = new ListenerGetData();


          Konfiguration konfiguration = new Konfiguration(_listenerGetData);


          _login = new Login();
          _login.GetKonfiguration = konfiguration;

          InformationSources informationSources = new InformationSources(_listenerGetData);
          ....
          [/highlight]

          Zu beginn wird nur ein TrayMenü mit entsprechendem Icon angelegt, dann können die einzelnen Menü-Items ausgewählt werden. Beim Start jedoch, werden schon Daten über Client-Server-Kommunikation eingelesen, bzw. sollte die Verbindung bestehen, deshalb übergebe ich ja das Objekt von der Klasse die die Daten einliest.

          Ich Initialisiere auch gleichzeitig die WPF-Fenster und setze Sie auf "Visibility= Visibility.Hidden;" sobald ich den Konstruktor aufrufe.

          Vielleicht liegt ja auch da der Haken. Leider kann ich das Real-Programm nicht posten (zu Umfangreich und nicht genehmigt).

          Gruß

          Lerando
          Attached Files
          Zuletzt editiert von gfoidl; 19.07.2012, 18:25. Reason: Beiträge zusammengeführt

          Comment


          • #6
            Ohhh, ich habe vergessen zu Erwähnen, dass ich WCF wie in dem o.g. Beispielprogrammen manuell Programmiert habe, also nicht mit "Hinzufügen" integriert habe und die Basis eine WPF-Anwendung ist.

            Comment


            • #7
              Hallo,

              die angehängten Projekte kann ich mir mangels Zeit nicht anschauen. Ich weiß nur, dass Sessions funktionieren wenn sie richtig implementiert sind. Probiers einfach mit 2 Konsolen-Programmen (Server + Client) aus, also mit einem Prototypen, erst dann setzt du das Erlernte in die WPF-Anwendung an. Sollte dabei an einer Stelle etwas nicht mehr so funktionieren wie es soll, kannst du die WPF-App. mit der Konsolen-App. vergleichen und so den Fehler ausfindig machen.

              mfG Gü
              "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

              Comment


              • #8
                Danke für Deine Antwort.

                Die o. g. Projekte ist das Beispiel, das ich erstellt habe als ich die Konsolenprogrammbeispiele erfolgreich durchgeführt habe.

                Heute Nacht ist mir noch ein Gedanke gekommen. Vielleicht habe ich auch wieder einen Gedankenfehler in der Programmlogik. Ich denke, dass ich die Initialisierung für den Client-Server-Connect zu spät durchführe. Ich muss aber meine Theorie noch testen.

                Der Client-Server-Connect (von meine Real-Programm) werde ich zum Programmstart festlegen, vielleicht gelingt es mir dann. Ich melde mich wieder.

                Nochmals Danke für Deine Antworten.

                Gruß Lerando

                Comment


                • #9
                  Leute, ich habs gefunden. Es war, wie vermutet, eine winzige Kleinigkeit. Ich habe im Real-Code einfach ein "I" vergessen. Es fehlte das "I" vor dem Interface-Namen der gebraucht wurde.
                  [highlight=csharp]
                  //vorher |||||||||||||||
                  [OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/DataAcquisition/OnMessageReceived")]
                  void OnMessageReceived(string message);

                  //nachher |||||||||||||||
                  [OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IDataAcquisition/OnMessageReceived")]
                  void OnMessageReceived(string message);
                  [/highlight]

                  Vieeelen Dank an gfoidl. Du hast mich sehr gut und professionell Unterstützt und ich habe wieder einmal einiges mehr über WCF erfahren.

                  Gruß Lerando

                  Comment


                  • #10
                    Hallo Lerando,

                    gerne.

                    tempuri solltest du noch ändern, dann passt es. Siehe How to eliminate tempuri.org from your service WSDL

                    Diese beiden Methoden sind oben aber nicht dabei? Ist jetzt auch egal.

                    Mit IsOneWay habe ich mit tw. geirrt, da es normal nicht nötig ist diesen Wert bei IsOneWay=false anzugeben, da dies der Standardwert ist. Lass das also weg, dann wird es übersichtlicher.

                    mfG Gü
                    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                    Comment


                    • #11
                      Vielen Dank für die Tips.

                      Gruß Lerando
                      Zuletzt editiert von gfoidl; 20.07.2012, 14:10. Reason: Fullquote entfernt.

                      Comment

                      Working...
                      X