Пример #1
0
        public async Task <WebSocket> ConnectAsync(Uri uri, CancellationToken cancellationToken)
        {
            WebSocketFeature webSocketFeature = null;
            var contextBuilder = new HttpContextBuilder(_application, AllowSynchronousIO, PreserveExecutionContext);

            contextBuilder.Configure(context =>
            {
                var request    = context.Request;
                var scheme     = uri.Scheme;
                scheme         = (scheme == "ws") ? "http" : scheme;
                scheme         = (scheme == "wss") ? "https" : scheme;
                request.Scheme = scheme;
                if (!request.Host.HasValue)
                {
                    request.Host = uri.IsDefaultPort
                        ? new HostString(HostString.FromUriComponent(uri).Host)
                        : HostString.FromUriComponent(uri);
                }
                request.Path     = PathString.FromUriComponent(uri);
                request.PathBase = PathString.Empty;
                if (request.Path.StartsWithSegments(_pathBase, out var remainder))
                {
                    request.Path     = remainder;
                    request.PathBase = _pathBase;
                }
                request.QueryString = QueryString.FromUriComponent(uri);
                request.Headers.Add(HeaderNames.Connection, new string[] { "Upgrade" });
                request.Headers.Add(HeaderNames.Upgrade, new string[] { "websocket" });
                request.Headers.Add(HeaderNames.SecWebSocketVersion, new string[] { "13" });
                request.Headers.Add(HeaderNames.SecWebSocketKey, new string[] { CreateRequestKey() });
                if (SubProtocols.Any())
                {
                    request.Headers.Add(HeaderNames.SecWebSocketProtocol, SubProtocols.ToArray());
                }

                request.Body = Stream.Null;

                // WebSocket
                webSocketFeature = new WebSocketFeature(context);
                context.Features.Set <IHttpWebSocketFeature>(webSocketFeature);

                ConfigureRequest?.Invoke(context.Request);
            });

            var httpContext = await contextBuilder.SendAsync(cancellationToken);

            if (httpContext.Response.StatusCode != StatusCodes.Status101SwitchingProtocols)
            {
                throw new InvalidOperationException("Incomplete handshake, status code: " + httpContext.Response.StatusCode);
            }
            if (webSocketFeature.ClientWebSocket == null)
            {
                throw new InvalidOperationException("Incomplete handshake");
            }

            return(webSocketFeature.ClientWebSocket);
        }
Пример #2
0
        public async Task <GameSocket> ConnectAsync(Uri uri, CancellationToken cancellationToken)
        {
            GameSocketFeature gameSocketFeature = null;
            var contextBuilder = new ProtoContextBuilder(_application, AllowSynchronousIO);

            contextBuilder.Configure(context =>
            {
                var request      = context.Request;
                var scheme       = uri.Scheme;
                scheme           = (scheme == "ws") ? "http" : scheme;
                scheme           = (scheme == "wss") ? "https" : scheme;
                request.Scheme   = scheme;
                request.Path     = PathString.FromUriComponent(uri);
                request.PathBase = PathString.Empty;
                if (request.Path.StartsWithSegments(_pathBase, out var remainder))
                {
                    request.Path     = remainder;
                    request.PathBase = _pathBase;
                }
                request.QueryString = QueryString.FromUriComponent(uri);
                request.Headers.Add("Connection", new string[] { "Upgrade" });
                request.Headers.Add("Upgrade", new string[] { "gamesocket" });
                request.Headers.Add("Sec-GameSocket-Version", new string[] { "13" });
                request.Headers.Add("Sec-GameSocket-Key", new string[] { CreateRequestKey() });
                request.Body = Stream.Null;

                // GameSocket
                gameSocketFeature = new GameSocketFeature(context);
                context.Features.Set <IProtoGameSocketFeature>(gameSocketFeature);

                ConfigureRequest?.Invoke(context.Request);
            });

            var httpContext = await contextBuilder.SendAsync(cancellationToken);

            if (httpContext.Response.StatusCode != StatusCodes.Status101SwitchingProtocols)
            {
                throw new InvalidOperationException("Incomplete handshake, status code: " + httpContext.Response.StatusCode);
            }
            if (gameSocketFeature.ClientGameSocket == null)
            {
                throw new InvalidOperationException("Incomplete handshake");
            }

            return(gameSocketFeature.ClientGameSocket);
        }
Пример #3
0
        public async Task <WebSocket> ConnectAsync(Uri uri, CancellationToken cancellationToken)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

            var cancellation = cancellationToken.Register(() => request.Abort());

            request.Headers[Constants.Headers.SecWebSocketVersion] = Constants.Headers.SupportedVersion;
            if (SubProtocols.Count > 0)
            {
                request.Headers[Constants.Headers.SecWebSocketProtocol] = string.Join(", ", SubProtocols);
            }

            ConfigureRequest?.Invoke(request);

            HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();

            cancellation.Dispose();

            InspectResponse?.Invoke(response);

            // TODO: Validate handshake
            HttpStatusCode statusCode = response.StatusCode;

            if (statusCode != HttpStatusCode.SwitchingProtocols)
            {
                response.Dispose();
                throw new InvalidOperationException("Incomplete handshake, invalid status code: " + statusCode);
            }
            // TODO: Validate Sec-WebSocket-Key/Sec-WebSocket-Accept

            string subProtocol = response.Headers[Constants.Headers.SecWebSocketProtocol];

            if (!string.IsNullOrEmpty(subProtocol) && !SubProtocols.Contains(subProtocol, StringComparer.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException("Incomplete handshake, the server specified an unknown sub-protocol: " + subProtocol);
            }

            var stream = response.GetResponseStream();

            return(CommonWebSocket.CreateClientWebSocket(stream, subProtocol, KeepAliveInterval, ReceiveBufferSize, UseZeroMask));
        }