source: trunk/CrypP2P/P2PManager.cs @ 1611

Last change on this file since 1611 was 1611, checked in by Paul Lelgemann, 12 years ago

o CrypWin: P2P world button always visible
o Changed behaviour of command line option "-p2p" and "-peer2peer": triggers autoconnect to peer-to-peer network during startup of CrypTool
o P2PEditor: "Start" button disabled and moved to settings pane for consistency
o CrypP2P: local workspace path is set to "%TEMP%/CrypTool", if not specified before
+ PeerToPeerProxy has a new setting to enable autoconnecting the peer-to-peer network, if it is not connected during workspace start

File size: 11.1 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.IO;
19using Cryptool.P2P.Internal;
20using Cryptool.P2P.Worker;
21using Cryptool.PluginBase;
22using Cryptool.PluginBase.Miscellaneous;
23using Cryptool.Plugins.PeerToPeer.Internal;
24using PeersAtPlay.P2PStorage.DHT;
25using PeersAtPlay.Util.Threading;
26
27namespace Cryptool.P2P
28{
29    public sealed class P2PManager
30    {
31        #region Singleton
32
33        public static readonly P2PManager Instance = new P2PManager();
34
35        private P2PManager()
36        {
37            P2PBase = new P2PBase(this);
38            ValidateSettings();
39
40            // to forward event from overlay/dht MessageReceived-Event from P2PBase
41            P2PBase.OnP2PMessageReceived += OnP2PMessageReceived;
42        }
43
44        #endregion
45
46        #region Variables
47
48        public P2PBase P2PBase { get; private set; }
49        public bool IsP2PConnecting { get; internal set; }
50        public bool IsAutoconnectConsoleOptionSet { get; set; }
51
52        #endregion
53
54        #region Events
55
56        public static event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
57
58        public delegate void P2PConnectionStateChangeEventHandler(object sender, bool newState);
59        public static event P2PConnectionStateChangeEventHandler OnP2PConnectionStateChangeOccurred;
60
61        public event P2PBase.P2PMessageReceived OnPeerMessageReceived;
62
63        #endregion Events
64
65        internal void FireConnectionStatusChange()
66        {
67            if (OnP2PConnectionStateChangeOccurred != null)
68            {
69                OnP2PConnectionStateChangeOccurred(this, IsP2PConnected());
70            }
71        }
72
73        public bool IsP2PConnected()
74        {
75            return P2PBase.Started;
76        }
77
78        public string UserInfo()
79        {
80            if (!IsP2PConnected())
81            {
82                return null;
83            }
84
85            string userName;
86            var userInfo = P2PBase.GetPeerId(out userName);
87            return userInfo + " (" + userName + ")";
88        }
89
90        public void HandleConnectOnStartup()
91        {
92            var isAutoconnectConfiguredOrRequested = P2PSettings.Default.ConnectOnStartup || IsAutoconnectConsoleOptionSet;
93            var isReadyToConnect = IsReadyToConnect();
94
95            if (isReadyToConnect && isAutoconnectConfiguredOrRequested)
96            {
97                GuiLogMessage("Connect on startup enabled. Establishing connection...", NotificationLevel.Info);
98                new ConnectionWorker(P2PBase).Start();
99            }
100        }
101
102        private bool IsReadyToConnect()
103        {
104            if (String.IsNullOrEmpty(P2PSettings.Default.PeerName))
105            {
106                GuiLogMessage("Peer-to-peer not fully configured: username missing.", NotificationLevel.Error);
107                return false;
108            }
109
110            if (String.IsNullOrEmpty(P2PSettings.Default.PeerName))
111            {
112                GuiLogMessage("Peer-to-peer not fully configured: world name missing.", NotificationLevel.Error);
113                return false;
114            }
115
116            return true;
117        }
118
119        public PeerId GetPeerId(out string userName)
120        {
121            return P2PBase.GetPeerId(out userName);
122        }
123
124        // to forward event from overlay/dht MessageReceived-Event from P2PBase
125        private void OnP2PMessageReceived(PeerId sourceAddr, byte[] data)
126        {
127            if (OnPeerMessageReceived != null)
128                OnPeerMessageReceived(sourceAddr, data);
129        }
130
131        private static void ValidateSettings()
132        {
133            if (String.IsNullOrEmpty(P2PSettings.Default.WorkspacePath))
134            {
135                var tempForUser = Path.Combine(Path.GetTempPath(), "CrypTool2");
136                Directory.CreateDirectory(tempForUser);
137                P2PSettings.Default.WorkspacePath = tempForUser;
138                P2PSettings.Default.Save();
139            }
140        }
141
142        #region Framework methods
143
144        public void GuiLogMessage(string message, NotificationLevel logLevel)
145        {
146            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, null, new GuiLogEventArgs(message, null, logLevel));
147        }
148
149        #endregion Framework methods
150
151        #region DHT operations (blocking)
152
153        /// <summary>
154        /// Stores the given data in the DHT. This method will block until a response has been received.
155        ///
156        /// The underlying DHT is versionend. Store attempts will fail, if the latest version has not been retrieved before.
157        /// </summary>
158        /// <param name="key">key to write</param>
159        /// <param name="data">data to write</param>
160        /// <exception cref="NotConnectedException">Will be thrown if the P2P system is not connected</exception>
161        /// <returns>true if the store attempt was successful, false otherwise</returns>
162        public static bool Store(string key, byte[] data)
163        {
164            if (!Instance.IsP2PConnected())
165                throw new NotConnectedException();
166
167            return Instance.P2PBase.SynchStore(key, data);
168        }
169
170        /// <summary>
171        /// Stores the given data in the DHT. This method will block until a response has been received.
172        ///
173        /// The underlying DHT is versionend. Store attempts will fail, if the latest version has not been retrieved before.
174        /// </summary>
175        /// <param name="key">key to write</param>
176        /// <param name="data">data to write</param>
177        /// <exception cref="NotConnectedException">Will be thrown if the P2P system is not connected</exception>
178        /// <returns>true if the store attempt was successful, false otherwise</returns>
179        public static bool Store(string key, string data)
180        {
181            if (!Instance.IsP2PConnected())
182                throw new NotConnectedException();
183           
184            return Instance.P2PBase.SynchStore(key, data);
185        }
186
187        /// <summary>
188        /// Retrieves the latest version of a given in key from the DHT. This method will block until a response has been received.
189        /// </summary>
190        /// <param name="key">key to retrieve</param>
191        /// <exception cref="NotConnectedException">Will be thrown if the P2P system is not connected</exception>
192        /// <returns>byte array containing the data</returns>
193        public static byte[] Retrieve(string key)
194        {
195            if (!Instance.IsP2PConnected())
196                throw new NotConnectedException();
197           
198            return Instance.P2PBase.SynchRetrieve(key);
199        }
200
201        /// <summary>
202        /// Removes a key and its data from the DHT. This method will block until a response has been received.
203        ///
204        /// The underlying DHT is versionend. Remove attempts will fail, if the latest version has not been retrieved before.
205        /// </summary>
206        /// <param name="key">key to remove</param>
207        /// <exception cref="NotConnectedException">Will be thrown if the P2P system is not connected</exception>
208        /// <returns>bool determining wether the attempt was successful</returns>
209        public static bool Remove(string key)
210        {
211            if (!Instance.IsP2PConnected())
212                throw new NotConnectedException();
213
214            return Instance.P2PBase.SynchRemove(key);
215        }
216
217        #endregion DHT operations (blocking)
218
219        #region DHT operations (non-blocking)
220
221        /// <summary>
222        /// Stores the given data in the DHT.
223        ///
224        /// The underlying DHT is versionend. Store attempts will fail, if the latest version has not been retrieved before.
225        /// </summary>
226        /// <param name="callback">Callback for asynchronous call</param>
227        /// <param name="key">key to write</param>
228        /// <param name="data">data to write</param>
229        /// <param name="asyncState">Arbitrary data, which will be included in the callback parameter</param>
230        /// <exception cref="NotConnectedException">Will be thrown if the P2P system is not connected</exception>
231        /// <returns>Guid identifying the request</returns>
232        public static Guid Store(AsyncCallback<StoreResult> callback, string key, byte[] data, object asyncState)
233        {
234            if (!Instance.IsP2PConnected())
235                throw new NotConnectedException();
236
237            return Instance.P2PBase.VersionedDht.Store(callback, key, data, asyncState);
238        }
239
240        /// <summary>
241        /// Retrieves the latest version of a given in key from the DHT.
242        /// </summary>
243        /// <param name="callback">Callback for asynchronous call</param>
244        /// <param name="key">key to retrieve</param>
245        /// <param name="asyncState">Arbitrary data, which will be included in the callback parameter</param>
246        /// <exception cref="NotConnectedException">Will be thrown if the P2P system is not connected</exception>
247        /// <returns>Guid identifying the request</returns>
248        public static Guid Retrieve(AsyncCallback<RetrieveResult> callback, string key, object asyncState)
249        {
250            if (!Instance.IsP2PConnected())
251                throw new NotConnectedException();
252
253            return Instance.P2PBase.Dht.Retrieve(callback, key, asyncState);
254        }
255
256        /// <summary>
257        /// Removes a key and its data from the DHT.
258        ///
259        /// The underlying DHT is versionend. Remove attempts will fail, if the latest version has not been retrieved before.
260        /// </summary>
261        /// <param name="callback">Callback for asynchronous call</param>
262        /// <param name="key">key to remove</param>
263        /// <param name="asyncState">Arbitrary data, which will be included in the callback parameter</param>
264        /// <exception cref="NotConnectedException">Will be thrown if the P2P system is not connected</exception>
265        /// <returns>Guid identifying the request</returns>
266        public static Guid Remove(AsyncCallback<RemoveResult> callback, string key, object asyncState)
267        {
268            if (!Instance.IsP2PConnected())
269                throw new NotConnectedException();
270
271            return Instance.P2PBase.VersionedDht.Remove(callback, key, asyncState);
272        }
273
274        #endregion DHT operations (non-blocking)
275
276        public void HandleShutdown()
277        {
278            if (IsP2PConnected())
279            {
280                new ConnectionWorker(P2PBase).Start();
281            }
282        }
283    }
284
285   
286}
Note: See TracBrowser for help on using the repository browser.