/// <summary> /// Establishes a new send-side HybridConnection and returns the Stream. /// </summary> public async Task <HybridConnectionStream> CreateConnectionAsync(IDictionary <string, string> requestHeaders) { TrackingContext trackingContext = CreateTrackingContext(this.Address); string traceSource = nameof(HybridConnectionClient) + "(" + trackingContext + ")"; // todo - Check if timeout helper needs to be started here. var timeoutHelper = TimeoutHelper.CreateOnly(this.OperationTimeout); RelayEventSource.Log.ObjectConnecting(traceSource, trackingContext); var webSocket = this.ClientWebSocketFactory.Create(); try { DefaultWebProxy.ConfigureProxy(webSocket.Options, this.Proxy); webSocket.Options.KeepAliveInterval = this.KeepAliveInterval; webSocket.Options.SetBuffer(this.ConnectionBufferSize, this.ConnectionBufferSize); webSocket.Options.SetRequestHeader(HybridConnectionConstants.Headers.RelayUserAgent, HybridConnectionConstants.ClientAgent); if (this.TokenProvider != null) { RelayEventSource.Log.GetTokenStart(traceSource); string audience = this.Address.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped); var token = await this.TokenProvider.GetTokenAsync(audience, TokenProvider.DefaultTokenTimeout).ConfigureAwait(false); RelayEventSource.Log.GetTokenStop(traceSource, token.ExpiresAtUtc); webSocket.Options.SetRequestHeader(RelayConstants.ServiceBusAuthorizationHeaderName, token.TokenString); } if (requestHeaders != null) { foreach (KeyValuePair <string, string> header in requestHeaders) { webSocket.Options.SetRequestHeader(header.Key, header.Value); } } // Build the websocket uri, e.g. "wss://contoso.servicebus.windows.net:443/$hc/endpoint1?sb-hc-action=connect&sb-hc-id=E2E_TRACKING_ID" Uri webSocketUri = HybridConnectionUtility.BuildUri( this.Address.Host, this.Address.Port, this.Address.AbsolutePath, this.Address.Query, HybridConnectionConstants.Actions.Connect, trackingContext.TrackingId); using (var cancelSource = new CancellationTokenSource(timeoutHelper.RemainingTime())) { await webSocket.ConnectAsync(webSocketUri, cancelSource.Token).ConfigureAwait(false); } RelayEventSource.Log.ObjectConnected(traceSource, trackingContext); return(new WebSocketStream(webSocket.WebSocket, trackingContext)); } catch (Exception exception) when(!WebSocketExceptionHelper.IsRelayContract(exception)) { throw RelayEventSource.Log.ThrowingException( WebSocketExceptionHelper.ConvertToRelayContract(exception, trackingContext, webSocket.Response, isListener: false), traceSource); } }
IClientWebSocket CreateWebSocket() { var clientWebSocket = ClientWebSocketFactory.Create(this.Listener.UseBuiltInClientWebSocket); clientWebSocket.Options.SetBuffer(this.Listener.ConnectionBufferSize, this.Listener.ConnectionBufferSize); DefaultWebProxy.ConfigureProxy(clientWebSocket.Options, this.Listener.Proxy); clientWebSocket.Options.KeepAliveInterval = HybridConnectionConstants.KeepAliveInterval; return(clientWebSocket); }
async Task EnsureRendezvousAsync(CancellationToken cancelToken) { if (this.rendezvousWebSocket == null) { RelayEventSource.Log.HybridHttpCreatingRendezvousConnection(this.TrackingContext); var clientWebSocket = ClientWebSocketFactory.Create(this.listener.UseBuiltInClientWebSocket); DefaultWebProxy.ConfigureProxy(clientWebSocket.Options, this.listener.Proxy); this.rendezvousWebSocket = clientWebSocket.WebSocket; await clientWebSocket.ConnectAsync(this.rendezvousAddress, cancelToken).ConfigureAwait(false); } }
async Task <WebSocket> ConnectAsync(CancellationToken cancellationToken) { this.listener.ThrowIfDisposed(); var webSocket = ClientWebSocketFactory.Create(this.listener.UseBuiltInClientWebSocket); try { var connectDelay = ConnectDelayIntervals[this.connectDelayIndex]; if (connectDelay != TimeSpan.Zero) { await Task.Delay(connectDelay, cancellationToken).ConfigureAwait(false); } RelayEventSource.Log.ObjectConnecting(this.listener); webSocket.Options.SetBuffer(this.bufferSize, this.bufferSize); DefaultWebProxy.ConfigureProxy(webSocket.Options, this.listener.Proxy); webSocket.Options.KeepAliveInterval = HybridConnectionConstants.KeepAliveInterval; webSocket.Options.SetRequestHeader(HybridConnectionConstants.Headers.RelayUserAgent, HybridConnectionConstants.ClientAgent); var token = await this.tokenRenewer.GetTokenAsync().ConfigureAwait(false); webSocket.Options.SetRequestHeader(RelayConstants.ServiceBusAuthorizationHeaderName, token.TokenString); // When we reconnect we need to remove the "_GXX" suffix otherwise trackingId gets longer after each reconnect string trackingId = TrackingContext.RemoveSuffix(this.listener.TrackingContext.TrackingId); // Build the websocket uri, e.g. "wss://contoso.servicebus.windows.net:443/$hc/endpoint1?sb-hc-action=listen&sb-hc-id=E2E_TRACKING_ID" var webSocketUri = HybridConnectionUtility.BuildUri( this.address.Host, this.address.Port, this.address.AbsolutePath, this.address.Query, HybridConnectionConstants.Actions.Listen, trackingId); await webSocket.ConnectAsync(webSocketUri, cancellationToken).ConfigureAwait(false); this.OnOnline(); RelayEventSource.Log.ObjectConnected(this.listener); return(webSocket.WebSocket); } catch (Exception exception) when(!WebSocketExceptionHelper.IsRelayContract(exception)) { throw RelayEventSource.Log.ThrowingException( WebSocketExceptionHelper.ConvertToRelayContract(exception, this.listener.TrackingContext, webSocket.Response), this.listener); } }