/// <summary> /// Removes the tunnel from the server and closes all connections. /// </summary> /// <param name="tunnel">The tunnel to be removed.</param> /// <param name="notifyServer">if set to <c>true</c> then notify the server of the closure.</param> protected virtual async Task RemoveTunnelAsync(ClientTunnel tunnel, bool notifyServer) { if (Tunnels.TryRemove(tunnel.Id, out var _)) { if (notifyServer) { var message = new Message { Type = MessageType.Notification, Code = MessageCode.CloseTunnelMessage }; message.Values["tunnel_id"] = tunnel.Id; await SendMessageAsync(message, CancellationToken.None); } var connections = Connections.Values.Where(a => a.TunnelId == tunnel.Id).ToList(); foreach (var connection in connections) { await RemoveConnectionAsync(connection, false); } await tunnel.CloseLocalAsync(); } }
/// <summary> /// Closes the requested tunnel and all outstanding connections. /// </summary> /// <param name="messageId">The message identifier.</param> /// <param name="tunnelId">The tunnel identifier.</param> /// <returns>A <see cref="Response"/> to be sent back to the client.</returns> protected virtual async Task <Response> CloseTunnelAsync(Guid messageId, Guid tunnelId) { if (Tunnels.TryRemove(tunnelId, out var tunnel)) { try { await RemoveTunnelAsync(tunnel, false); } catch (Exception ex) { return(new Response(messageId, false, ex.Message)); } return(new Response(messageId, true, "Tunnel closed.")); } else { return(new Response(messageId, false, "Tunnel not found.")); } }