private void Connect()
{
int port = uri.Port;
if (port == -1)
port = 80;
client = new TcpClient(uri.Host, port);
try
{
string webSocketKey = NewWebSocketKey();
string handshake = NewHandshakeRequest(webSocketKey);
Stream stream = client.GetStream();
byte[] handshakeBytes = Encoding.UTF8.GetBytes(handshake);
stream.Write(handshakeBytes, 0, handshakeBytes.Length);
stream.Flush();
byte[] b = new byte[8096];
string response = "";
while (true)
{
int readBytes = stream.Read(b, 0, b.Length);
if (readBytes <= 0)
break;
response += Encoding.UTF8.GetString(b, 0, readBytes);
if (response.EndsWith("\r\n\r\n"))
break;
}
if (!response.StartsWith("HTTP/1.1 101 "))
throw new IOException("websocket is not supported");
IDictionary headers = new Hashtable();
string[] lines = Regex.Split(response, "\r\n");
foreach (string line in lines)
{
int p = line.IndexOf(':');
if (p < 0)
continue;
string key = line.Substring(0, p).Trim().ToLower();
string val = line.Substring(p + 1).Trim();
headers[key] = val;
}
string upgrade = GetHeader(headers, "upgrade");
string connection = GetHeader(headers, "connection");
string accept = GetHeader(headers, "sec-websocket-accept");
if (upgrade != "websocket")
throw new IOException("Unexpected Upgrade value: " + upgrade);
if (connection != "Upgrade")
throw new IOException("Unexpected Connection value: " + connection);
SHA1 sha1 = new SHA1Managed();
string input = webSocketKey + WEBSOCKET_KEY_TRAILER;
byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
string expected = Convert.ToBase64String(hash);
if (expected != accept)
throw new IOException("invalid websocket accept: key " + webSocketKey + ", expected " + expected + ", actual " + accept);
ReadContext ctx = new ReadContext();
ctx.expected = 2;
client.GetStream().BeginRead(ctx.headerBuffer, 0, ctx.expected, new AsyncCallback(ReadCallback), ctx);
}
catch (Exception e)
{
if (OnError != null)
{
try { OnError(e); }
catch (Exception) {}
}
Close(e);
throw;
}
}