source: trunk/CrypP2P/Internal/ConnectionManager.cs @ 2129

Last change on this file since 2129 was 2129, checked in by Sven Rech, 11 years ago

P2P reconnect only when SystemLeft event is triggered by connection failure

File size: 6.6 KB
Line 
1/*
2   Copyright 2010 Paul Lelgemann, University of Duisburg-Essen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Threading;
19using System.Windows.Threading;
20using Cryptool.P2P.Worker;
21using Cryptool.PluginBase;
22
23namespace Cryptool.P2P.Internal
24{
25    public class ConnectionManager
26    {
27        #region Delegates
28
29        public delegate void P2PConnectionStateChangeEventHandler(object sender, bool newState);
30
31        #endregion
32
33        private readonly object connectLock = new object();
34        private readonly P2PBase p2PBase;
35        private DateTime lastConnectionAttempt;
36        private Dispatcher guiLogDispatcher = null;
37        private bool disconnected = false;
38
39        public ConnectionManager(P2PBase p2PBase)
40        {
41            this.p2PBase = p2PBase;
42
43            bool reconnecting = false;
44            p2PBase.OnSystemLeft += new P2PBase.SystemLeft(delegate
45                                                               {
46                                                                   if (disconnected)
47                                                                       return;
48
49                                                                   //Enforce a minimum of 2 seconds between each connection attempt:
50                                                                   if ((lastConnectionAttempt - DateTime.Now).TotalSeconds < 2)
51                                                                       Thread.Sleep(2000);
52
53                                                                   P2PManager.GuiLogMessage("Lost P2P Connection. Try reconnecting...",
54                                                                        NotificationLevel.Error);
55                                                                   reconnecting = true;
56                                                                   this.Connect();
57                                                                   guiLogDispatcher = Dispatcher.CurrentDispatcher;
58                                                               });
59            p2PBase.OnSystemJoined += new P2PBase.SystemJoined(delegate
60                                                                   {
61                                                                       if (p2PBase.IsConnected && reconnecting)
62                                                                       {
63                                                                           //TODO: This doesn't work. GuiLogMessage will never be shown:
64                                                                           if (guiLogDispatcher != null)
65                                                                                guiLogDispatcher.Invoke(DispatcherPriority.Send, (SendOrPostCallback)delegate
66                                                                                {
67                                                                                    P2PManager.GuiLogMessage("Successfully reconnected!",
68                                                                                        NotificationLevel.Balloon);
69                                                                                }, null);
70                                                                           reconnecting = false;
71                                                                       }
72                                                                   });
73        }
74
75        public bool IsConnecting { get; internal set; }
76        public event P2PConnectionStateChangeEventHandler OnP2PConnectionStateChangeOccurred;
77
78        public void Connect()
79        {
80            lock (connectLock)
81            {
82                disconnected = false;
83                lastConnectionAttempt = DateTime.Now;
84
85                if (p2PBase.IsConnected || IsConnecting)
86                {
87                    P2PManager.GuiLogMessage("Cannot connect, already connected or connecting.",
88                                             NotificationLevel.Warning);
89                    return;
90                }
91
92                if (!IsReadyToConnect())
93                {
94                    P2PManager.GuiLogMessage("Cannot connect, configuration is broken.", NotificationLevel.Warning);
95                    return;
96                }
97
98                IsConnecting = true;
99            }
100
101            P2PManager.GuiLogMessage("Dispatching connect request with ConnectionWorker.", NotificationLevel.Debug);
102            new ConnectionWorker(p2PBase, this).Start();
103        }
104
105        public void Disconnect()
106        {
107            lock (connectLock)
108            {
109                disconnected = true;
110                if (!p2PBase.IsConnected || IsConnecting)
111                {
112                    P2PManager.GuiLogMessage("Cannot disconnect, no connection or connection attempt active.",
113                                             NotificationLevel.Warning);
114                    return;
115                }
116
117                IsConnecting = true;
118            }
119
120            P2PManager.GuiLogMessage("Dispatching disconnect request with ConnectionWorker.", NotificationLevel.Debug);
121            new ConnectionWorker(p2PBase, this).Start();
122        }
123
124        public bool IsReadyToConnect()
125        {
126            if (String.IsNullOrEmpty(P2PSettings.Default.PeerName))
127            {
128                P2PManager.GuiLogMessage("Peer-to-peer not fully configured: username missing.", NotificationLevel.Error);
129                return false;
130            }
131
132            if (String.IsNullOrEmpty(P2PSettings.Default.PeerName))
133            {
134                P2PManager.GuiLogMessage("Peer-to-peer not fully configured: world name missing.",
135                                         NotificationLevel.Error);
136                return false;
137            }
138
139            return true;
140        }
141
142        public void FireConnectionStatusChange()
143        {
144            if (OnP2PConnectionStateChangeOccurred != null)
145            {
146                OnP2PConnectionStateChangeOccurred(this, p2PBase.IsConnected);
147            }
148        }
149    }
150}
Note: See TracBrowser for help on using the repository browser.