@@ -26,14 +26,17 @@ public class ConnectionManager
26
26
/// <summary>
27
27
/// The connections to other peers. Key is the base58 hash of the peer ID.
28
28
/// </summary>
29
- ConcurrentDictionary < string , PeerConnection > connections = new ConcurrentDictionary < string , PeerConnection > ( ) ;
29
+ ConcurrentDictionary < string , List < PeerConnection > > connections = new ConcurrentDictionary < string , List < PeerConnection > > ( ) ;
30
30
31
31
string Key ( Peer peer ) => peer . Id . ToBase58 ( ) ;
32
+ string Key ( MultiHash id ) => id . ToBase58 ( ) ;
32
33
33
34
/// <summary>
34
35
/// Gets the current connections.
35
36
/// </summary>
36
- public IEnumerable < PeerConnection > Connections => connections . Values ;
37
+ public IEnumerable < PeerConnection > Connections => connections . Values
38
+ . SelectMany ( c => c )
39
+ . Where ( c => c . Stream != null && c . Stream . CanRead && c . Stream . CanWrite ) ;
37
40
38
41
/// <summary>
39
42
/// Determines if a connection exists to the specified peer.
@@ -68,20 +71,17 @@ public bool IsConnected(Peer peer)
68
71
/// </remarks>
69
72
public bool TryGet ( Peer peer , out PeerConnection connection )
70
73
{
71
- if ( ! connections . TryGetValue ( Key ( peer ) , out connection ) )
74
+ connection = null ;
75
+ if ( ! connections . TryGetValue ( Key ( peer ) , out List < PeerConnection > conns ) )
72
76
{
73
77
return false ;
74
78
}
75
79
76
- // Is nolonger active.
77
- if ( connection . Stream == null || ! connection . Stream . CanRead || ! connection . Stream . CanWrite )
78
- {
79
- Remove ( connection ) ;
80
- connection = null ;
81
- return false ;
82
- }
80
+ connection = conns
81
+ . Where ( c => c . Stream != null && c . Stream . CanRead && c . Stream . CanWrite )
82
+ . FirstOrDefault ( ) ;
83
83
84
- return true ;
84
+ return connection != null ;
85
85
}
86
86
87
87
/// <summary>
@@ -100,39 +100,20 @@ public bool TryGet(Peer peer, out PeerConnection connection)
100
100
/// </remarks>
101
101
public PeerConnection Add ( PeerConnection connection )
102
102
{
103
- if ( connections . TryGetValue ( Key ( connection . RemotePeer ) , out PeerConnection existing ) )
104
- {
105
- // If the same connection.
106
- if ( connection == existing )
103
+ connections . AddOrUpdate (
104
+ Key ( connection . RemotePeer ) ,
105
+ ( key ) => new List < PeerConnection > { connection } ,
106
+ ( key , conns ) =>
107
107
{
108
- return connection ;
108
+ if ( ! conns . Contains ( connection ) )
109
+ {
110
+ conns . Add ( connection ) ;
111
+ }
112
+ return conns ;
109
113
}
114
+ ) ;
110
115
111
- // If existing is dead, then use current connection.
112
- if ( existing . Stream == null || ! existing . Stream . CanRead || ! existing . Stream . CanWrite )
113
- {
114
- var address = connection . RemotePeer . ConnectedAddress ;
115
- Remove ( existing ) ;
116
- connection . RemotePeer . ConnectedAddress = address ;
117
- // fall thru to add logic
118
- }
119
- else
120
- {
121
- var address = existing . RemotePeer . ConnectedAddress ;
122
- log . Debug ( $ "duplicate { connection . RemoteAddress } , keeping { existing . RemoteAddress } ") ;
123
- connection . Dispose ( ) ;
124
- existing . RemotePeer . ConnectedAddress = address ;
125
- return existing ;
126
- }
127
- }
128
-
129
- if ( ! connections . TryAdd ( Key ( connection . RemotePeer ) , connection ) )
130
- {
131
- // This case should not happen.
132
- connection . Dispose ( ) ;
133
- return connections [ Key ( connection . RemotePeer ) ] ;
134
- }
135
-
116
+ connection . Closed += ( s , e ) => Remove ( e ) ;
136
117
return connection ;
137
118
}
138
119
@@ -156,29 +137,30 @@ public bool Remove(PeerConnection connection)
156
137
return false ;
157
138
}
158
139
159
- var q = connections . TryRemove ( Key ( connection . RemotePeer ) , out PeerConnection _ ) ;
160
- connection . Dispose ( ) ;
161
140
162
- return q ;
163
- }
141
+ if ( ! connections . TryGetValue ( Key ( connection . RemotePeer ) , out List < PeerConnection > conns ) )
142
+ {
143
+ connection . Dispose ( ) ;
144
+ return false ;
145
+ }
146
+ if ( ! conns . Contains ( connection ) )
147
+ {
148
+ connection . Dispose ( ) ;
149
+ return false ;
150
+ }
164
151
165
- /// <summary>
166
- /// Remove the connection to the peer.
167
- /// </summary>
168
- /// <param name="peer">
169
- /// The peer to remove.
170
- /// </param>
171
- /// <returns>
172
- /// <b>true</b> if a connection was removed; otherwise, <b>false</b>.
173
- /// </returns>
174
- public bool Remove ( Peer peer )
175
- {
176
- var connection = connections . Values . FirstOrDefault ( c => c . RemotePeer . Id == peer . Id ) ;
177
- return Remove ( connection ) ;
152
+ connection . Dispose ( ) ;
153
+ conns . Remove ( connection ) ;
154
+ if ( conns . Count > 0 )
155
+ {
156
+ var last = conns . Last ( ) ;
157
+ last . RemotePeer . ConnectedAddress = last . RemoteAddress ;
158
+ }
159
+ return true ;
178
160
}
179
161
180
162
/// <summary>
181
- /// Remove the connection to the peer ID.
163
+ /// Remove and close all connection tos the peer ID.
182
164
/// </summary>
183
165
/// <param name="id">
184
166
/// The ID of a <see cref="Peer"/> to remove.
@@ -188,21 +170,26 @@ public bool Remove(Peer peer)
188
170
/// </returns>
189
171
public bool Remove ( MultiHash id )
190
172
{
191
- var connection = connections . Values . FirstOrDefault ( c => c . RemotePeer . Id == id ) ;
192
- return Remove ( connection ) ;
173
+ if ( ! connections . TryRemove ( Key ( id ) , out List < PeerConnection > conns ) )
174
+ {
175
+ return false ;
176
+ }
177
+ foreach ( var conn in conns )
178
+ {
179
+ conn . Dispose ( ) ;
180
+ }
181
+ return true ;
193
182
}
194
183
195
184
/// <summary>
196
185
/// Removes and closes all connections.
197
186
/// </summary>
198
187
public void Clear ( )
199
188
{
200
-
201
- for ( var connection = connections . Values . LastOrDefault ( ) ;
202
- connection != null ;
203
- connection = connections . Values . LastOrDefault ( ) )
189
+ var conns = connections . Values . SelectMany ( c => c ) . ToArray ( ) ;
190
+ foreach ( var conn in conns )
204
191
{
205
- Remove ( connection ) ;
192
+ Remove ( conn ) ;
206
193
}
207
194
}
208
195
}
0 commit comments