source: trunk/CrypP2P/P2PManager.cs @ 1580

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

+ Introduced dirty hack to shutdown the peer-to-peer network in CrypWin

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