Skip to content

Commit 5471bb7

Browse files
committed
Xmas Eve 2018 commit
- Refactor server-side message handling - Lots of help by Paul from Mirror Discord
1 parent e321cf5 commit 5471bb7

File tree

1 file changed

+93
-66
lines changed

1 file changed

+93
-66
lines changed

IgnoranceTransport/IgnoranceTransport.cs

Lines changed: 93 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ public class IgnoranceTransport : TransportLayer
5151
private Address serverAddress;
5252
private Peer clientPeer;
5353

54-
private Dictionary<int, Peer> knownPeerConnections; // Known connections dictonary since ENET is a little weird.
55-
private int serverConnectionCount = 1; // Used by our dictionary to map ENET Peers to connections. Start at 1 just to be safe.
54+
private Dictionary<int, Peer> knownConnIDToPeers; // Known connections dictonary since ENET is a little weird.
55+
private Dictionary<Peer, int> knownPeersToConnIDs; // Vice versa.
56+
57+
private int serverConnectionCount = 1; // Used by our dictionary to map ENET Peers to connections. Start at 1 just to be safe, connection 0 will be localClient.
5658

5759
// This section defines what classic UNET channels refer to.
5860
private readonly PacketFlags[] packetSendMethods =
@@ -75,15 +77,17 @@ public class IgnoranceTransport : TransportLayer
7577
// -- INITIALIZATION -- //
7678
public IgnoranceTransport()
7779
{
78-
Debug.LogFormat("EXPERIMENTAL Ignorance build {0} for Mirror 2018 ready! Report bugs and donate coffee at https://github.com/SoftwareGuy/Ignorance.", TransportVersion);
80+
Debug.LogFormat("EXPERIMENTAL Ignorance Transport v{0} for Mirror 2018 ready! Report bugs and donate coffee at https://github.com/SoftwareGuy/Ignorance.", TransportVersion);
7981
}
8082

8183
// -- CLIENT WORLD -- //
82-
public virtual bool ClientConnected() {
84+
public virtual bool ClientConnected()
85+
{
8386
return clientPeer.IsSet && clientPeer.State == PeerState.Connected;
8487
}
8588

86-
public virtual void ClientConnect(string address, int port) {
89+
public virtual void ClientConnect(string address, int port)
90+
{
8791
// Fire up ENET-C#'s backend.
8892
if (!libraryInitialized)
8993
{
@@ -108,21 +112,25 @@ public virtual void ClientConnect(string address, int port) {
108112
ClientReceiveLoop(client);
109113
}
110114

111-
private async void ClientReceiveLoop(Host clientHost) {
115+
private async void ClientReceiveLoop(Host clientHost)
116+
{
112117
try
113118
{
114119
while (true)
115120
{
121+
if (!clientHost.IsSet) break;
122+
123+
Event incomingEvent;
116124
// Get the next message from the client peer object.
117-
clientHost.Service(0, out Event incomingEvent);
125+
clientHost.Service(0, out incomingEvent);
118126
switch (incomingEvent.Type)
119127
{
120128
case EventType.Connect:
121-
// TODO: Emit a message when this happens.
122-
129+
Debug.LogFormat("Ignorance Transport: Successfully connected to peer located at {0}", incomingEvent.Peer.IP);
123130
OnClientConnect?.Invoke();
124131
break;
125132
case EventType.Disconnect:
133+
// Nothing to do here, break the loop.
126134
return;
127135
case EventType.Timeout:
128136
throw new TimeoutException("Ignorance Transport: Our peer connection timed out.");
@@ -131,24 +139,29 @@ private async void ClientReceiveLoop(Host clientHost) {
131139
await Await.NextUpdate();
132140
break;
133141
case EventType.Receive:
134-
// Got data.
142+
// Data coming in.
135143
byte[] data = new byte[incomingEvent.Packet.Length];
136144
incomingEvent.Packet.CopyTo(data);
137145
incomingEvent.Packet.Dispose();
138146
OnClientData?.Invoke(data);
139147
break;
140148
}
141149
}
142-
} catch (Exception exception) {
150+
}
151+
catch (Exception exception)
152+
{
143153
// Something went wrong - just like Windows 10.
144154
OnClientError?.Invoke(exception);
145-
} finally {
155+
}
156+
finally
157+
{
146158
// We disconnected, got fed an error message or we got a Disconnect.
147159
OnClientDisconnect?.Invoke();
148160
}
149161
}
150162

151-
public virtual void ClientSend(int channelId, byte[] data) {
163+
public virtual void ClientSend(int channelId, byte[] data)
164+
{
152165
Packet mailingPigeon = default(Packet);
153166
bool sendingPacketWasSuccessful; // really needed?
154167

@@ -167,18 +180,21 @@ public virtual void ClientSend(int channelId, byte[] data) {
167180
mailingPigeon.Create(data, packetSendMethods[channelId]);
168181
// probably should get the bool result from this again
169182
sendingPacketWasSuccessful = clientPeer.Send(0, ref mailingPigeon);
170-
183+
if (!sendingPacketWasSuccessful) Debug.LogWarning("Ignorance Transport: Packet sending apparently wasn't successful.");
184+
171185
return;
172186
}
173187

174-
public virtual void ClientDisconnect() {
188+
public virtual void ClientDisconnect()
189+
{
175190
if (clientPeer.IsSet) clientPeer.DisconnectNow(0);
176191
if (client != null) client.Dispose();
177192
client = null;
178193
}
179194

180195
// -- SERVER WORLD -- //
181-
public virtual bool ServerActive() {
196+
public virtual bool ServerActive()
197+
{
182198
if (!libraryInitialized) return false;
183199

184200
if (server != null) return server.IsSet;
@@ -198,7 +214,9 @@ public virtual void ServerStart(string address, int port, int maxConnections)
198214
// Initialize our references.
199215
server = new Host();
200216
serverAddress = new Address();
201-
knownPeerConnections = new Dictionary<int, Peer>();
217+
218+
knownConnIDToPeers = new Dictionary<int, Peer>();
219+
knownPeersToConnIDs = new Dictionary<Peer, int>();
202220

203221
// Bind if we have an address specified.
204222
if (!string.IsNullOrEmpty(address))
@@ -221,83 +239,87 @@ private async void ServerReceiveLoop(Host server)
221239
{
222240
try
223241
{
224-
while(true) {
225-
server.Service(0, out Event incomingEvent);
242+
while (true)
243+
{
244+
if (!server.IsSet) break;
245+
246+
Event incomingEvent;
247+
server.Service(0, out incomingEvent);
226248

227249
switch (incomingEvent.Type)
228250
{
229251
case EventType.Connect:
230-
// TODO: Emit a message when this happens.
252+
Debug.LogFormat("Ignorance Transport: New connection from {0}", incomingEvent.Peer.IP);
231253

232254
// New client connected, let's set them up.
233255
int newClientConnectionId = serverConnectionCount;
234256
// Increment our next server connection counter.
235257
serverConnectionCount++;
236-
// Map them in our dictionary.
237-
knownPeerConnections.Add(newClientConnectionId, incomingEvent.Peer);
258+
// Map them in our dictionaries
259+
knownPeersToConnIDs.Add(incomingEvent.Peer, newClientConnectionId);
260+
knownConnIDToPeers.Add(newClientConnectionId, incomingEvent.Peer);
238261
// Invoke the async callback.
239262
OnServerConnect?.Invoke(newClientConnectionId);
240263
break;
241264
case EventType.Receive:
242265
// Got data.
243-
byte[] data = new byte[incomingEvent.Packet.Length];
244-
245-
// Come up with a better way of doing this, Coburn...
246-
foreach (KeyValuePair<int, Peer> entry in knownPeerConnections)
266+
// Only process that data if the peer is known.
267+
if (knownPeersToConnIDs.ContainsKey(incomingEvent.Peer))
247268
{
248-
if (entry.Value.ID == incomingEvent.Peer.ID)
249-
{
250-
incomingEvent.Packet.CopyTo(data);
251-
incomingEvent.Packet.Dispose();
252-
OnServerData?.Invoke(entry.Key, data);
253-
254-
// No need to keep going through the list. Halt.
255-
break;
256-
}
269+
byte[] data = new byte[incomingEvent.Packet.Length];
270+
271+
incomingEvent.Packet.CopyTo(data);
272+
incomingEvent.Packet.Dispose();
273+
OnServerData?.Invoke(knownPeersToConnIDs[incomingEvent.Peer], data);
257274
}
275+
258276
break;
259277
case EventType.Disconnect:
260-
case EventType.Timeout:
261-
// TODO: Emit a message when this happens.
262-
// Look them up. Not the easiest way of doing this, though.
263-
264-
foreach (KeyValuePair<int, Peer> entry in knownPeerConnections)
278+
Debug.LogFormat("Ignorance Transport: Acknowledging disconnection on connection ID {0} ", knownPeersToConnIDs[incomingEvent.Peer]);
279+
if (knownPeersToConnIDs.ContainsKey(incomingEvent.Peer))
265280
{
266-
if (entry.Value.ID == incomingEvent.Peer.ID)
267-
{
268-
int disconnectedConnectionId = entry.Key;
269-
OnServerDisconnect?.Invoke(disconnectedConnectionId);
270-
knownPeerConnections.Remove(entry.Key);
271-
break;
272-
}
281+
OnServerDisconnect?.Invoke(knownPeersToConnIDs[incomingEvent.Peer]);
282+
PeerDisconnectedInternal(incomingEvent.Peer);
273283
}
274284
break;
285+
case EventType.Timeout:
286+
OnServerError?.Invoke(knownPeersToConnIDs[incomingEvent.Peer], new TimeoutException("Ignorance Transport: Timeout occurred on connection " + knownPeersToConnIDs[incomingEvent.Peer]));
287+
OnServerDisconnect?.Invoke(knownPeersToConnIDs[incomingEvent.Peer]);
288+
PeerDisconnectedInternal(incomingEvent.Peer);
289+
break;
275290
case EventType.None:
276291
// Nothing is happening, so we need to wait until the next frame.
277292
await Await.NextUpdate();
278293
break;
279294
}
280-
}
295+
}
281296
}
282297
catch (Exception exception)
283298
{
284-
// What would go here??
285299
Debug.LogFormat("Server exception caught: {0}", exception.ToString());
300+
OnServerError?.Invoke(-1, exception);
286301
}
287302
finally
288303
{
289-
// What would go here??
290-
Debug.Log("FIXME: I dunno what to do here");
304+
Debug.Log("Ignorance Transport: Server receive loop finished.");
291305
}
292306
}
293307

308+
private void PeerDisconnectedInternal(Peer peer)
309+
{
310+
// Clean up dictionaries.
311+
if (knownConnIDToPeers.ContainsKey(knownPeersToConnIDs[peer])) knownConnIDToPeers.Remove(knownPeersToConnIDs[peer]);
312+
if (knownPeersToConnIDs.ContainsKey(peer)) knownPeersToConnIDs.Remove(peer);
313+
}
314+
294315
public virtual void ServerStartWebsockets(string address, int port, int maxConnections)
295316
{
296317
Debug.LogError("Ignorance Transport does not support Websockets. Aborting...");
297318
return;
298319
}
299320

300-
public virtual void ServerSend(int connectionId, int channelId, byte[] data) {
321+
public virtual void ServerSend(int connectionId, int channelId, byte[] data)
322+
{
301323
Packet mailingPigeon = default(Packet);
302324
bool wasTransmissionSuccessful;
303325

@@ -307,44 +329,49 @@ public virtual void ServerSend(int connectionId, int channelId, byte[] data) {
307329
return;
308330
}
309331

310-
if (knownPeerConnections.ContainsKey(connectionId)) {
311-
Peer target = knownPeerConnections[connectionId];
332+
if (knownConnIDToPeers.ContainsKey(connectionId))
333+
{
334+
Peer target = knownConnIDToPeers[connectionId];
312335
mailingPigeon.Create(data, packetSendMethods[channelId]);
313336

314337
wasTransmissionSuccessful = target.Send(0, ref mailingPigeon);
338+
if (!wasTransmissionSuccessful) Debug.LogWarning("Ignorance Transport: Server-side packet sending apparently wasn't successful.");
315339
return;
316340
}
317341
}
318342

319343
public virtual bool ServerDisconnect(int connectionId)
320344
{
321-
if (knownPeerConnections.ContainsKey(connectionId)) {
322-
knownPeerConnections[connectionId].Disconnect(0);
345+
if (knownConnIDToPeers.ContainsKey(connectionId))
346+
{
347+
knownConnIDToPeers[connectionId].Disconnect(0);
323348
return true;
324349
}
325350

326351
return false;
327352
}
328353

329-
public virtual bool GetConnectionInfo(int connectionId, out string address) {
354+
public virtual bool GetConnectionInfo(int connectionId, out string address)
355+
{
330356
address = "(invalid)";
331357

332-
if (knownPeerConnections.ContainsKey(connectionId))
358+
if (knownConnIDToPeers.ContainsKey(connectionId))
333359
{
334-
address = knownPeerConnections[connectionId].IP;
360+
address = knownConnIDToPeers[connectionId].IP;
335361
return true;
336362
}
337363

338364
return false;
339365
}
340366

341-
public virtual void ServerStop() {
342-
foreach (KeyValuePair<int, Peer> entry in knownPeerConnections)
343-
{
344-
entry.Value.DisconnectNow(0);
345-
}
367+
public virtual void ServerStop()
368+
{
369+
foreach (KeyValuePair<int, Peer> entry in knownConnIDToPeers) entry.Value.DisconnectNow(0);
346370

347371
// Don't forget to dispose stuff.
372+
knownConnIDToPeers = new Dictionary<int, Peer>();
373+
knownPeersToConnIDs = new Dictionary<Peer, int>();
374+
348375
if (server != null) server.Dispose();
349376
server = null;
350377
}
@@ -446,7 +473,7 @@ public void EnableCompressionOnServer()
446473
/// </summary>
447474
public void EnableCompressionOnClient()
448475
{
449-
if(client != null && client.IsSet)
476+
if (client != null && client.IsSet)
450477
{
451478
client.EnableCompression();
452479
}
@@ -551,4 +578,4 @@ public void EnableParanoidLogging(bool enable)
551578
verboseLoggingEnabled = enable;
552579
}
553580
}
554-
}
581+
}

0 commit comments

Comments
 (0)