public void SocketErrorShouldCleanup()
        {
            var sockets = SocketTestTools.CreateConnection();
            var sut = new ServerClientContext(new BufferSlice(65535));
            var service = Substitute.For<INetworkService>();
            sut.Assign(sockets.Server, service);
            bool isDisconnected = false;
            sut.Disconnected += (sender, args) => isDisconnected = true;

            sockets.Client.Dispose();
            Thread.Sleep(100);

            isDisconnected.Should()
                          .BeTrue("The receive callback should have triggered a disconnect and also cleaned up");
            sut.GetType().GetField("_socket", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(sut).Should().BeNull("Since cleanup should have been made.");
        }
        public void ServerDisconnectThenSend()
        {
            var sockets = SocketTestTools.CreateConnection();
            var sut = new ServerClientContext(new BufferSlice(65535));
            var service = Substitute.For<INetworkService>();
            sut.Assign(sockets.Server, service);
            bool isDisconnected = false;
            sut.Disconnected += (sender, args) => isDisconnected = true;

            sockets.Server.Shutdown(SocketShutdown.Both);
            sut.Send(new BufferSlice(10), 10);
            Thread.Sleep(100);

            isDisconnected.Should()
                          .BeFalse("The receive callback should have triggered a disconnect and also cleaned up");
            var socket = (Socket)sut.GetType().GetField("_socket", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(sut);
            socket.Should().BeNull("Should cleanup from the receive event not have been made.");
        }
 /// <summary>
 /// A client has disconnected from the server (either network failure or by the remote end point)
 /// </summary>
 /// <param name="context">Disconnected client</param>
 /// <remarks>Calls to <see cref="ServerClientContext.Close()"/> will also trigger this method, but with <see cref="SocketError.Success"/>. 
 /// <para>The method is typically used to clean up your own implementation. The context, socket ETC have already been cleaned up.</para></remarks>
 protected virtual void OnClientDisconnected(ServerClientContext context)
 {
 }
 /// <summary>
 /// A client has disconnected from the server (either network failure or by the remote end point)
 /// </summary>
 /// <param name="context">Disconnected client</param>
 /// <remarks>Calls to <see cref="ServerClientContext.Close()"/> will also trigger this method, but with <see cref="SocketError.Success"/>.
 /// <para>The method is typically used to clean up your own implementation. The context, socket ETC have already been cleaned up.</para></remarks>
 protected virtual void OnClientDisconnected(ServerClientContext context)
 {
 }