Exemple #1
0
        public async Task ConnectAsync(string url)
        {
            Uri    uri   = new Uri(url);
            string query = uri.PathAndQuery;
            bool   ssl   = uri.Scheme.ToLower().StartsWith("wss");
            int    port  = uri.Port > 0 ? uri.Port : (ssl ? 443 : 80);

            await client.ConnectAsync(uri.Host, port);

            ConnectionStream stream = new ConnectionStream(ref client, ssl);

            if (ssl)
            {
                await stream.Authenticate(ConnectionStream.AuthMode.Client, uri.Host);
            }

            if (!(await Handshake(stream, uri, port)))
            {
                state = WebsockState.Closed;
                throw new Exception("Failed connection at handshake");
            }

            protocol = new WebsockProtocol(ref stream);
            state    = WebsockState.Open;
            try {
                while (true)
                {
                    await OnMessage(await protocol.GetMessage());
                }
            } catch (WebsockCloseException ex) {
                await OnClose(ex.Code, ex.Reason);
            } finally {
                protocol.Dispose();
            }
        }
Exemple #2
0
        // Deny client with http error message
        private async Task <bool> RejectClient(ConnectionStream stream, string errorMessage)
        {
            byte[] errorData = Encoding.UTF8.GetBytes(HttpErrorTemplate
                                                      .Replace("{Content}", errorMessage)
                                                      .Replace("{ContentType}", "text/plain")
                                                      .Replace("{ContentLength}", errorMessage.Length.ToString()));
            await stream.WriteAsync(errorData, errorData.Length);

            stream.Dispose();
            return(false);
        }
Exemple #3
0
        // handle incoming clients
        private async Task HandleClient(ConnectionStream stream)
        {
            if (!(await HandshakeClient(stream)))
            {
                return;
            }
            WebsockServerClient serverClient = new WebsockServerClient(this, ref stream);

            clients.Add(serverClient);
            await serverClient.StartAsync();
        }
Exemple #4
0
        private async Task <bool> Handshake(ConnectionStream stream, Uri uri, int port)
        {
            state = WebsockState.Connecting;
            string handshakeData = HttpHandshakeData
                                   .Replace("{Path}", uri.PathAndQuery)
                                   .Replace("{Host}", uri.Host)
                                   .Replace("{Scheme}", uri.Scheme)
                                   .Replace("{Port}", port.ToString())
                                   .Replace("{Key}", GenerateKey());
            await stream.WriteAsync(handshakeData);

            string response = Encoding.UTF8.GetString(await stream.ReadAsync());

            return(response.Split('\n')[0].Split(' ')[1] == "101");
        }
Exemple #5
0
        // Perform websocket handshake with client
        private async Task <bool> HandshakeClient(ConnectionStream stream)
        {
            // read and parse http request data
            byte[] httpData = await stream.ReadAsync();

            HttpPacket packet = new HttpPacket(httpData);

            // client requests checks
            if (!packet.Method.ToLower().StartsWith("get"))
            {
                return(await RejectClient(stream, "Only allows GET Requests"));
            }
            if (!packet.Headers.ContainsKey("Sec-WebSocket-Key"))
            {
                return(await RejectClient(stream, "No WebSocket-Key found"));
            }
            if (!packet.Headers.ContainsKey("Upgrade"))
            {
                return(await RejectClient(stream, "Upgrade header not set"));
            }
            else if (!packet.Headers["Upgrade"].ToLower().StartsWith("websocket"))
            {
                return(await RejectClient(stream, "Upgrade header not websocket"));
            }
            if (!packet.Headers.ContainsKey("Connection"))
            {
                return(await RejectClient(stream, "Connection header not set"));
            }
            else if (!packet.Headers["Connection"].ToLower().StartsWith("upgrade"))
            {
                return(await RejectClient(stream, "Connection header not upgrade"));
            }

            // generate websocket key, send response to client and complete handshake
            httpData = Encoding.UTF8.GetBytes(HttpHandshakeSucces.Replace(
                                                  "{WebsockKey}", GenerateKey(packet.Headers["Sec-WebSocket-Key"])));
            await stream.WriteAsync(httpData, httpData.Length);

            return(true);
        }
Exemple #6
0
 public WebsockProtocol(ref ConnectionStream stream)
 {
     this.stream = stream;
     dataBuilder = new MemoryStream();
     callbacks   = new Queue <Func <byte[], Task> >();
 }
Exemple #7
0
 public WebsockServerClient(WebsockServer server, ref ConnectionStream stream)
 {
     this.server   = server;
     this.protocol = new WebsockProtocol(ref stream);
 }