Пример #1
0
        private async Task ConnectClientInternal()
        {
            if (_socket != null)
            {
                throw new Exception("connect() is already called");
            }
            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    = WebSocketHelper.CreateClientKey();
                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 = WebSocketHelper.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, ex.Message));
                }
            }
            finally
            {
                Disconnect();
            }
        }
Пример #2
0
        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();
                      }

                  });
        }