kerryjiang / WebSocket4Net

A popular .NET WebSocket Client
752 stars 272 forks source link

Make sure WebSocket fired all Closed events when Disposing #162

Open darxis opened 4 years ago

darxis commented 4 years ago

In my app I need to dispose the WebSocket but if the WebSocket is connected then I would like to make sure that the Closed event will get fired. If I call the WebSocket.Dispose() when the WS is connected then it will close the connection but the Closed event will not get fired. How can I easily make sure that it will get fired? Do I need to implement custom logic for that?

Here is my wrapper for WebSocket:

internal class WebSocket4NetWrapper : IWebSocketWrapper
    {
        private bool _disposed;

        private readonly WebSocket _ws;

        public event EventHandler Connected;

        public event EventHandler<WebSocketClientMessageReceivedEventArgs> MessageReceived;

        public event EventHandler<WebSocketClientDataReceivedEventArgs> DataReceived;

        public event EventHandler Disconnected;

        public WebSocketState State
        {
            get
            {
                var state = _ws.State;
                switch (state)
                {
                    case WebSocket4NetState.None:
                        return WebSocketState.None;
                    case WebSocket4NetState.Connecting:
                        return WebSocketState.Connecting;
                    case WebSocket4NetState.Open:
                        return WebSocketState.Open;
                    case WebSocket4NetState.Closing:
                        return WebSocketState.Closing;
                    case WebSocket4NetState.Closed:
                        return WebSocketState.Closed;
                    default:
                        throw UnhandledEnumValueException.Create(state);
                }
            }
        }

        public WebSocket4NetWrapper(WebSocket webSocket)
        {
            _ws = webSocket;
            _ws.Opened += WebSocketOnOpen;
            _ws.Closed += WebSocketOnClose;
            _ws.MessageReceived += WebSocketOnMessageReceived;
            _ws.DataReceived += WebSocketOnDataReceived;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            if (disposing)
            {
                _ws.Dispose();
            }

            _disposed = true;
        }

        public void Connect()
        {
            _ws.Open();
        }

        public void Disconnect()
        {
            _ws.Close();
        }

        public void SendMessage(string message)
        {
            _ws.Send(message);
        }

        public void SendMessage(byte[] message)
        {
            _ws.Send(message, 0, message.Length);
        }

        private void WebSocketOnOpen(object sender, EventArgs e)
        {
            Connected?.Invoke(this, EventArgs.Empty);
        }

        private void WebSocketOnClose(object sender, EventArgs e)
        {
            Disconnected?.Invoke(this, EventArgs.Empty);
        }

        private void WebSocketOnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            MessageReceived?.Invoke(this, new WebSocketClientMessageReceivedEventArgs(e.Message));
        }

        private void WebSocketOnDataReceived(object sender, DataReceivedEventArgs e)
        {
            DataReceived?.Invoke(this, new WebSocketClientDataReceivedEventArgs(e.Data));
        }
    }