예제 #1
0
        /// <summary>
        /// Sends the handshake asynchronous.
        /// </summary>
        /// <param name="handshake">The handshake.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task <WebSocketResponseHandshake> SendHandshakeAsync(WebSocketRequestHandshake handshake, CancellationToken cancellationToken)
        {
            var oldState = Interlocked.CompareExchange(ref _state, WebSocketState.Opening, WebSocketState.Connected);

            if (oldState != WebSocketState.Connected)
            {
                throw new InvalidOperationException(ErrorMessages.InvalidState + _state);
            }

            var data = handshake.ToString();

            await this.SendAsync(data, Encoding.UTF8, cancellationToken);

            var responseHeaders = new List <string>();
            var line            = await _tcp.ReadLineAsync(cancellationToken);

            while (!String.IsNullOrEmpty(line))
            {
                responseHeaders.Add(line);
                line = await _tcp.ReadLineAsync(cancellationToken);
            }

            var response = WebSocketResponseHandshake.Parse(responseHeaders);

            if (response.StatusCode != HttpStatusCode.SwitchingProtocols)
            {
                var versions = response.SecWebSocketVersion;
                if (versions != null && !versions.Intersect(Consts.SupportedClientVersions).Any())
                {
                    throw new WebSocketException(WebSocketErrorCode.HandshakeVersionNotSupported);
                }

                throw new WebSocketException(WebSocketErrorCode.HandshakeInvalidStatusCode);
            }

            var challenge        = Encoding.UTF8.GetBytes(handshake.SecWebSocketKey + Consts.ServerGuid);
            var hash             = Sha1Digest.ComputeHash(challenge);
            var calculatedAccept = Convert.ToBase64String(hash);

            if (response.SecWebSocketAccept != calculatedAccept)
            {
                throw new WebSocketException(WebSocketErrorCode.HandshakeInvalidSecWebSocketAccept);
            }

            response.RequestMessage = handshake;

            Interlocked.Exchange(ref _state, WebSocketState.Open);


            return(response);
        }
예제 #2
0
        /// <summary>
        /// Sends the default handshake asynchronous.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public Task <WebSocketResponseHandshake> SendHandshakeAsync(CancellationToken cancellationToken)
        {
            var handshake = new WebSocketRequestHandshake(_uri);

            foreach (var extension in _extensions)
            {
                handshake.AddExtension(extension);
            }

            if (!string.IsNullOrEmpty(_subProtocol))
            {
                handshake.SecWebSocketProtocol = new[] { _subProtocol };
            }

            return(this.SendHandshakeAsync(handshake, cancellationToken));
        }
        /// <summary>
        /// Sends the handshake asynchronous.
        /// </summary>
        /// <param name="handshake">The handshake.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task<WebSocketResponseHandshake> SendHandshakeAsync(WebSocketRequestHandshake handshake, CancellationToken cancellationToken)
        {
            var oldState = Interlocked.CompareExchange(ref _state, WebSocketState.Opening, WebSocketState.Connected);
            if (oldState != WebSocketState.Connected)
                throw new InvalidOperationException(ErrorMessages.InvalidState + _state);

            var data = handshake.ToString();
            await this.SendAsync(data, Encoding.UTF8, cancellationToken);

            var responseHeaders = new List<string>();
            var line = await _tcp.ReadLineAsync(cancellationToken);
            while (!String.IsNullOrEmpty(line))
            {
                responseHeaders.Add(line);
                line = await _tcp.ReadLineAsync(cancellationToken);
            }

            var response = WebSocketResponseHandshake.Parse(responseHeaders);
            if (response.StatusCode != HttpStatusCode.SwitchingProtocols)
            {
                var versions = response.SecWebSocketVersion;
                if (versions != null && !versions.Intersect(Consts.SupportedClientVersions).Any())
                    throw new WebSocketException(WebSocketErrorCode.HandshakeVersionNotSupported);                    
                    
                throw new WebSocketException(WebSocketErrorCode.HandshakeInvalidStatusCode);
            }

            var challenge = Encoding.UTF8.GetBytes(handshake.SecWebSocketKey + Consts.ServerGuid);
            var hash = Sha1Digest.ComputeHash(challenge);
            var calculatedAccept = Convert.ToBase64String(hash);

            if (response.SecWebSocketAccept != calculatedAccept)
                throw new WebSocketException(WebSocketErrorCode.HandshakeInvalidSecWebSocketAccept);       

            response.RequestMessage = handshake;

            Interlocked.Exchange(ref _state, WebSocketState.Open);

            return response;
        }
 /// <summary>
 /// Sends the handshake asynchronous.
 /// </summary>
 /// <param name="handshake">The handshake.</param>
 /// <returns></returns>
 public Task<WebSocketResponseHandshake> SendHandshakeAsync(WebSocketRequestHandshake handshake)
 {
     return this.SendHandshakeAsync(handshake, CancellationToken.None);
 }
        /// <summary>
        /// Sends the default handshake asynchronous.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public Task<WebSocketResponseHandshake> SendHandshakeAsync(CancellationToken cancellationToken)
        {
            var handshake = new WebSocketRequestHandshake(_uri);
            foreach (var extension in _extensions)
                handshake.AddExtension(extension);

            return this.SendHandshakeAsync(handshake, cancellationToken);
        }
예제 #6
0
 /// <summary>
 /// Sends the handshake asynchronous.
 /// </summary>
 /// <param name="handshake">The handshake.</param>
 /// <returns></returns>
 public Task <WebSocketResponseHandshake> SendHandshakeAsync(WebSocketRequestHandshake handshake)
 {
     return(this.SendHandshakeAsync(handshake, CancellationToken.None));
 }
        /// <summary>
        /// Sends the default handshake asynchronous.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public Task<WebSocketResponseHandshake> SendHandshakeAsync(CancellationToken cancellationToken)
        {
            var handshake = new WebSocketRequestHandshake(_uri);
            foreach (var extension in _extensions)
                handshake.AddExtension(extension);

            if (!string.IsNullOrEmpty(_subProtocol))
            {
                handshake.SecWebSocketProtocol = new[] {_subProtocol};
            }
            
            return this.SendHandshakeAsync(handshake, cancellationToken);
        }