Example #1
0
        /// <summary>
        /// Connect with options specified
        /// </summary>
        /// <param name="uri">The WebSocket uri to connect to (e.g. ws://example.com or wss://example.com for SSL)</param>
        /// <param name="options">The WebSocket client options</param>
        /// <param name="token">The optional cancellation token</param>
        /// <returns>A connected web socket instance</returns>
        public async Task <WebSocket> ConnectAsync(Uri uri, WebSocketClientOptions options, CancellationToken token = default(CancellationToken))
        {
            Guid   guid      = Guid.NewGuid();
            string host      = uri.Host;
            int    port      = uri.Port;
            var    tcpClient = new TcpClient(host, port);

            tcpClient.NoDelay = options.NoDelay;
            // removed this because it throws unsupported in Unity.
            //tcpClient.Client.DualMode = true;
            string uriScheme = uri.Scheme.ToLower();
            bool   useSsl    = uriScheme == "wss" || uriScheme == "https";

            // removed this because the TcpClient connects when it is constructed.
            //IPAddress ipAddress;
            //if (IPAddress.TryParse(host, out ipAddress))
            //{
            //    Events.Log.ClientConnectingToIpAddress(guid, ipAddress.ToString(), port);
            //    await tcpClient.ConnectAsync(ipAddress, port);
            //}
            //else
            //{
            //    Events.Log.ClientConnectingToHost(guid, host, port);
            //    await tcpClient.ConnectAsync(host, port);
            //}

            token.ThrowIfCancellationRequested();
            Stream stream = GetStream(guid, tcpClient, useSsl, host);

            return(await PerformHandshake(guid, uri, stream, options, token));
        }
        /// <summary>
        /// Connect with options specified
        /// </summary>
        /// <param name="uri">The WebSocket uri to connect to (e.g. ws://example.com or wss://example.com for SSL)</param>
        /// <param name="options">The WebSocket client options</param>
        /// <param name="token">The optional cancellation token</param>
        /// <returns>A connected web socket instance</returns>
        public async Task <WebSocket> ConnectAsync(Uri uri, WebSocketClientOptions options, CancellationToken token = default(CancellationToken))
        {
            Guid   guid      = Guid.NewGuid();
            string host      = uri.Host;
            int    port      = uri.Port;
            var    tcpClient = new TcpClient();

            tcpClient.NoDelay = options.NoDelay;
            string    uriScheme = uri.Scheme.ToLower();
            bool      useSsl    = uriScheme == "wss" || uriScheme == "https";
            IPAddress ipAddress;

            if (IPAddress.TryParse(host, out ipAddress))
            {
                Events.Log.ClientConnectingToIpAddress(guid, ipAddress.ToString(), port);
                await tcpClient.ConnectAsync(ipAddress, port);
            }
            else
            {
                Events.Log.ClientConnectingToHost(guid, host, port);
                await tcpClient.ConnectAsync(host, port);
            }

            token.ThrowIfCancellationRequested();
            Stream stream = GetStream(guid, tcpClient, useSsl, host);

            return(await PerformHandshake(guid, uri, stream, options, token));
        }
        private async Task <WebSocket> PerformHandshake(Guid guid, Uri uri, Stream stream,
                                                        WebSocketClientOptions options, CancellationToken token)
        {
            var rand       = new Random();
            var keyAsBytes = new byte[16];

            rand.NextBytes(keyAsBytes);
            var secWebSocketKey      = Convert.ToBase64String(keyAsBytes);
            var additionalHeaders    = GetAdditionalHeaders(options.AdditionalHttpHeaders);
            var handshakeHttpRequest = $"GET {uri.PathAndQuery} HTTP/1.1\r\n" +
                                       $"Host: {uri.Host}:{uri.Port}\r\n" +
                                       "Upgrade: websocket\r\n" +
                                       "Connection: Upgrade\r\n" +
                                       $"Sec-WebSocket-Key: {secWebSocketKey}\r\n" +
                                       $"Origin: http://{uri.Host}:{uri.Port}\r\n" +
                                       $"Sec-WebSocket-Protocol: {options.SecWebSocketProtocol}\r\n" +
                                       additionalHeaders +
                                       "Sec-WebSocket-Version: 13\r\n\r\n";

            var httpRequest = Encoding.UTF8.GetBytes(handshakeHttpRequest);

            stream.Write(httpRequest, 0, httpRequest.Length);
            Events.Log.HandshakeSent(guid, handshakeHttpRequest);
            return(await ConnectAsync(stream, secWebSocketKey, options, token));
        }
        /// <summary>
        /// Connect with options specified
        /// </summary>
        /// <param name="uri">The WebSocket uri to connect to (e.g. ws://example.com or wss://example.com for SSL)</param>
        /// <param name="options">The WebSocket client options</param>
        /// <param name="token">The optional cancellation token</param>
        /// <returns>A connected web socket instance</returns>
        public async Task <WebSocket> ConnectAsync(Uri uri, WebSocketClientOptions options, CancellationToken token = default(CancellationToken))
        {
            var    guid      = Guid.NewGuid();
            string host      = uri.Host;
            int    port      = uri.Port;
            var    tcpClient = new TcpClient(AddressFamily.InterNetworkV6);

            tcpClient.NoDelay         = options.NoDelay;
            tcpClient.Client.DualMode = true;
            string uriScheme = uri.Scheme.ToLower();
            bool   useSsl    = uriScheme == "wss" || uriScheme == "https";

            if (IPAddress.TryParse(host, out IPAddress ipAddress))
            {
                Events.Log.ClientConnectingToIpAddress(guid, ipAddress.ToString(), port);
                await tcpClient.ConnectAsync(ipAddress, port);
            }
            else
            {
                Events.Log.ClientConnectingToHost(guid, host, port);
                await tcpClient.ConnectAsync(host, port);
            }

            token.ThrowIfCancellationRequested();
            Stream stream    = GetStream(guid, tcpClient, useSsl, host);
            var    websocket = await PerformHandshake(guid, uri, stream, options, token) as WebSocketImplementation;

            websocket.TcpClient = tcpClient;

            return(websocket);
        }
        /// <summary>
        /// Connect with a stream that has already been opened and HTTP websocket upgrade request sent
        /// This function will check the handshake response from the server and proceed if successful
        /// Use this function if you have specific requirements to open a conenction like using special http headers and cookies
        /// You will have to build your own HTTP websocket upgrade request
        /// You may not even choose to use TCP/IP and this function will allow you to do that
        /// </summary>
        /// <param name="responseStream">The full duplex response stream from the server</param>
        /// <param name="secWebSocketKey">The secWebSocketKey you used in the handshake request</param>
        /// <param name="options">The WebSocket client options</param>
        /// <param name="token">The optional cancellation token</param>
        /// <returns></returns>
        public async Task <WebSocket> ConnectAsync(Stream responseStream, string secWebSocketKey,
                                                   WebSocketClientOptions options, CancellationToken token = default(CancellationToken))
        {
            var guid = Guid.NewGuid();

            return(await ConnectAsync(guid, responseStream, secWebSocketKey, options.KeepAliveInterval,
                                      options.SecWebSocketExtensions, options.IncludeExceptionInCloseResponse, token));
        }
Example #6
0
        /// <summary>
        /// Connect with options specified
        /// </summary>
        /// <param name="uri">The WebSocket uri to connect to (e.g. ws://example.com or wss://example.com for SSL)</param>
        /// <param name="options">The WebSocket client options</param>
        /// <param name="token">The optional cancellation token</param>
        /// <returns>A connected web socket instance</returns>
        public async Task <WebSocket> ConnectAsync(Uri uri, WebSocketClientOptions options, CancellationToken token = default(CancellationToken))
        {
            Guid   guid      = Guid.NewGuid();
            string host      = uri.Host;
            int    port      = uri.Port;
            string uriScheme = uri.Scheme.ToLower();
            bool   useSsl    = uriScheme == "wss" || uriScheme == "https";
            Stream stream    = await GetStream(guid, useSsl, options.NoDelay, host, port, token);

            return(await PerformHandshake(guid, uri, stream, options, token));
        }