/// <summary>
        /// Attempt to open a new event channel from the specified HTTP listener context.
        /// </summary>
        /// <param name="listenerContext">
        /// HTTP listener context.
        /// </param>
        /// <param name="openedAction">
        /// Action to perform when web socket is opened.
        /// Will never be called if web channel can't be opened.
        /// </param>
        /// <param name="closedAction">
        /// Action to perform when web socket is closed.
        /// Will never be called if web channel can't be opened.
        /// </param>
        /// <remarks>
        /// If <paramref name="listenerContext"/> does not represent a web socket request, or if
        /// web socket channel could not be established, an appropriate status code will be
        /// returned via <paramref name="listenerContext"/>'s Response property.
        /// </remarks>
        public static async void TryOpenAsync(
            HttpListenerContext listenerContext, Action<WebSocketEventChannel> openedAction, Action<WebSocketEventChannel> closedAction)
        {
            var socketContext = await HandleWebSocketRequestAsync(listenerContext);

            if (socketContext != null)
            {
                var channel = new WebSocketEventChannel(socketContext, closedChannel => closedAction(closedChannel as WebSocketEventChannel));
                openedAction(channel);
            }
        }
        /// <summary>
        /// Attempt to open a new event channel from the specified HTTP listener context.
        /// </summary>
        /// <param name="listenerContext">
        /// HTTP listener context.
        /// </param>
        /// <param name="openedAction">
        /// Action to perform when web socket is opened.
        /// Will never be called if web channel can't be opened.
        /// </param>
        /// <param name="closedAction">
        /// Action to perform when web socket is closed.
        /// Will never be called if web channel can't be opened.
        /// </param>
        /// <remarks>
        /// If <paramref name="listenerContext"/> does not represent a web socket request, or if
        /// web socket channel could not be established, an appropriate status code will be
        /// returned via <paramref name="listenerContext"/>'s Response property.
        /// </remarks>
        public static async void TryOpenAsync(
            HttpListenerContext listenerContext, Action <WebSocketEventChannel> openedAction, Action <WebSocketEventChannel> closedAction)
        {
            var socketContext = await HandleWebSocketRequestAsync(listenerContext);

            if (socketContext != null)
            {
                var channel = new WebSocketEventChannel(socketContext, closedChannel => closedAction(closedChannel as WebSocketEventChannel));
                openedAction(channel);
            }
        }
 /// <summary>
 /// Safely makes a copy of the list of stream channels.
 /// </summary>
 /// <returns>Array containing the stream channels.</returns>
 public static IEnumerable<WebSocketEventChannel> SafeCopy(this List<WebSocketEventChannel> list)
 {
     var channels = new WebSocketEventChannel[list.Count];
     list.CopyTo(channels);
     return channels;
 }