private void Disconnect() { if (_socket != null) { try { _socket.Dispose(); _socket = null; _closed = true; } catch (Exception ex) { if (this.OnError != null) { this.OnError(this, ex); } } } }
protected virtual void Dispose(bool disposing) { if (_disposed) { return; } if (disposing) { if (this._socket != null) { this._socket.Dispose(); this._socket = null; } } _disposed = true; }
private async Task ConnectClientInternal() { if (_socket != null) { throw new Exception("connect() is already called"); } await Task.Factory.StartNew(async () => { try { int port = (_uri.Port != -1) ? _uri.Port : (_uri.Scheme.Equals("wss") ? 443 : 80); string path = (_uri.AbsolutePath != null) ? _uri.AbsolutePath : "/"; if (_uri.Query != null) { path += "?" + _uri.Query; } string originScheme = _uri.Scheme.Equals("wss") ? "https" : "http"; Uri origin = new Uri(originScheme + "://" + _uri.Host); // To fix: get Origin from extraHeaders if set there. this._socket = new InternalSocket(); await this._socket.ConnectAsync(_uri.Host, port); if (_uri.Scheme.Equals("wss")) { await this._socket.UpgradeToSslAsync(_uri.Host); } string key = CreateSecKey(); DataWriter writer = new DataWriter(_socket.OutputStream); writer.WriteString("GET " + path + " HTTP/1.1\r\n"); writer.WriteString("Upgrade: websocket\r\n"); writer.WriteString("Connection: Upgrade\r\n"); writer.WriteString("Host: " + _uri.Host + "\r\n"); writer.WriteString("Origin: " + origin.ToString() + "\r\n"); writer.WriteString("Sec-WebSocket-Key: " + key + "\r\n"); writer.WriteString("Sec-WebSocket-Version: 13\r\n"); if (_extraRequestHeaders != null) { foreach (Http.Header header in _extraRequestHeaders) { writer.WriteString(header.ToString() + "\r\n"); } } writer.WriteString("\r\n"); await writer.StoreAsync(); //异步发送数据 writer.DetachStream(); //分离 writer.Dispose(); //结束writer DataReader reader = new DataReader(_socket.InputStream); reader.ByteOrder = ByteOrder.LittleEndian; //// Read HTTP response status line. var startLine = await ReadLine(reader); if (startLine == null) { throw new Exception("Received no reply from server."); } Http.StatusLine statusLine = new Http.StatusLine(startLine); int statusCode = statusLine.StatusCode; if (statusCode != 101) { throw new Exception("wrong HTTP response code: " + statusCode); } // Read HTTP response headers. string line; while ((line = await ReadLine(reader)) != null && line.Length > 0) { Http.Header header = new Http.Header(line); Debug.WriteLine(line); if (header.HeaderName.Equals("Sec-WebSocket-Accept", StringComparison.OrdinalIgnoreCase)) { string receivedAccept = header.HeaderValue; string shouldBeAccept = CreateAccept(key); if (!receivedAccept.Equals(shouldBeAccept)) throw new Exception("Wrong Sec-WebSocket-Accept: " + receivedAccept + " should be: " + shouldBeAccept); } if (_serverResponseHeaders == null) { _serverResponseHeaders = new List<Http.Header>(); } _serverResponseHeaders.Add(header); } if (this.Opened != null) { this.Opened(this, EventArgs.Empty); } //Upgrade: websocket //Connection: Upgrade //Sec-WebSocket-Accept: 1xY289lHcEMbLpEBgOYRBBL9N9c= //Sec-WebSocket-Protocol: chat //Content-Type: application/octet-stream //Seq-Id: 667035124 // Read & process frame while (true) { FrameParser.Frame frame = await FrameParser.ReadFrame(reader); if (frame != null) { await ProcessIncomingFrame(frame); } } } catch (IOException ex) { if (this.Closed != null) { this.Closed(this, new WebSocketClosedEventArgs(0, "EOF")); } } catch (Exception ex) { if (this.Closed != null) { this.Closed(this, new WebSocketClosedEventArgs(0, "Exception")); } } finally { Disconnect(); } }); }