fix: #2357 (the second bug): NetworkServer.DisconnectAllConnections now iterates a copy of connections.Values to InvalidOperationException in cases where Transport.ServerDisconnect calls Mirror's OnServerDisconnect event immediately, which calls NetworkServer.OnDisconnected(connectionId), which would remove the connection while DisconnectAllConnections is iterating over them.

This commit is contained in:
vis2k 2020-10-22 11:36:18 +02:00
parent 4840289a92
commit a0af716aa7

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Mirror.RemoteCalls; using Mirror.RemoteCalls;
using UnityEngine; using UnityEngine;
@ -338,7 +339,18 @@ public static void DisconnectAll()
/// </summary> /// </summary>
public static void DisconnectAllConnections() public static void DisconnectAllConnections()
{ {
foreach (NetworkConnection conn in connections.Values) // disconnect and remove all connections.
// we can not use foreach here because if
// conn.Disconnect -> Transport.ServerDisconnect calls
// OnDisconnect -> NetworkServer.OnDisconnect(connectionId)
// immediately then OnDisconnect would remove the connection while
// we are iterating here.
// see also: https://github.com/vis2k/Mirror/issues/2357
// this whole process should be simplified some day.
// until then, let's copy .Values to avoid InvalidOperatinException.
// note that this is only called when stopping the server, so the
// copy is no performance problem.
foreach (NetworkConnection conn in connections.Values.ToList())
{ {
conn.Disconnect(); conn.Disconnect();
OnDisconnected(conn); OnDisconnected(conn);