public async Task <Task> ConnectAsync( EndPoint endPoint, bool sendHandshakeRequestMessage = true, bool expectedHandshakeResponseMessage = true) { if (sendHandshakeRequestMessage) { using (var memoryStream = new MemoryStream()) { HandshakeProtocol.WriteRequestMessage(new HandshakeRequestMessage(_protocol.Name), memoryStream); await Connection.Application.Output.WriteAsync(memoryStream.ToArray()); } } var connection = endPoint.OnConnectedAsync(Connection); if (expectedHandshakeResponseMessage) { // note that the handshake response might not immediately be readable // e.g. server is waiting for request, times out after configured duration, // and sends response with timeout error HandshakeResponseMessage = (HandshakeResponseMessage) await ReadAsync(true).OrTimeout(); } return(connection); }
private bool ProcessHandshakeResponse(ref ReadOnlyMemory <byte> data) { HandshakeResponseMessage message; try { // read first message out of the incoming data if (!TextMessageParser.TryParseMessage(ref data, out var payload)) { throw new InvalidDataException("Unable to parse payload as a handshake response message."); } message = HandshakeProtocol.ParseResponseMessage(payload); } catch (Exception ex) { // shutdown if we're unable to read handshake Log.ErrorReceivingHandshakeResponse(_logger, ex); Shutdown(ex); return(false); } if (!string.IsNullOrEmpty(message.Error)) { // shutdown if handshake returns an error Log.HandshakeServerError(_logger, message.Error); Shutdown(); return(false); } return(true); }
public void GlobalSetup() { using (var writer = new MemoryBufferWriter()) { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); var handshakeResponseResult = new ReadResult(new ReadOnlySequence <byte>(writer.ToArray()), false, false); _pipe = new TestDuplexPipe(); _pipe.AddReadResult(new ValueTask <ReadResult>(handshakeResponseResult)); } _tcs = new TaskCompletionSource <ReadResult>(); _pipe.AddReadResult(new ValueTask <ReadResult>(_tcs.Task)); var connection = new TestConnection(); // prevents keep alive time being activated connection.Features.Set <IConnectionInherentKeepAliveFeature>(new TestConnectionInherentKeepAliveFeature()); connection.Transport = _pipe; var protocol = Protocol == "json" ? (IHubProtocol) new JsonHubProtocol() : new MessagePackHubProtocol(); _hubConnection = new HubConnection(() => connection, protocol, new NullLoggerFactory()); _hubConnection.StartAsync().GetAwaiter().GetResult(); _arguments = new object[ArgumentCount]; for (int i = 0; i < _arguments.Length; i++) { _arguments[i] = "Hello world!"; } }
public async void ServiceConnectionShouldIgnoreFirstHandshakeResponse() { var factory = new TestClientConnectionFactory(); var connection = MockServiceConnection(null, factory); // create a connection with migration header. await connection.OnClientConnectedAsyncForTest(new OpenConnectionMessage("foo", new Claim[0]) { Headers = new Dictionary <string, StringValues> { { Constants.AsrsMigrateIn, "another-server" } } }); Assert.Equal(1, factory.Connections.Count); var context = factory.Connections[0]; Assert.True(context.IsMigrated); var message = new AspNetCore.SignalR.Protocol.HandshakeResponseMessage(""); HandshakeProtocol.WriteResponseMessage(message, context.Transport.Output); await context.Transport.Output.FlushAsync(); var task = context.Transport.Input.ReadAsync(); await Task.Delay(100); // nothing should be written into the transport Assert.False(task.IsCompleted); // but the `migrated` status should remain False (readonly) Assert.True(context.IsMigrated); }
public void GlobalSetup() { var writer = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); _handshakeResponseResult = new ReadResult(new ReadOnlySequence <byte>(writer.ToArray()), false, false); } finally { MemoryBufferWriter.Return(writer); } _pipe = new TestDuplexPipe(); var hubConnectionBuilder = new HubConnectionBuilder(); hubConnectionBuilder.WithUrl("http://doesntmatter"); var delegateConnectionFactory = new DelegateConnectionFactory(endPoint => { var connection = new DefaultConnectionContext(); // prevents keep alive time being activated connection.Features.Set <IConnectionInherentKeepAliveFeature>(new TestConnectionInherentKeepAliveFeature()); connection.Transport = _pipe; return(new ValueTask <ConnectionContext>(connection)); }); hubConnectionBuilder.Services.AddSingleton <IConnectionFactory>(delegateConnectionFactory); _hubConnection = hubConnectionBuilder.Build(); }
public void GlobalSetup() { var writer = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); _handshakeResponseResult = new ReadResult(new ReadOnlySequence <byte>(writer.ToArray()), false, false); } finally { MemoryBufferWriter.Return(writer); } _pipe = new TestDuplexPipe(); var hubConnectionBuilder = new HubConnectionBuilder(); hubConnectionBuilder.WithHubProtocol(new JsonHubProtocol()); hubConnectionBuilder.WithConnectionFactory(format => { var connection = new DefaultConnectionContext(); // prevents keep alive time being activated connection.Features.Set <IConnectionInherentKeepAliveFeature>(new TestConnectionInherentKeepAliveFeature()); connection.Transport = _pipe; return(Task.FromResult <ConnectionContext>(connection)); }); _hubConnection = hubConnectionBuilder.Build(); }
public void GlobalSetup() { var arguments = new object[ArgumentCount]; for (var i = 0; i < arguments.Length; i++) { arguments[i] = "Hello world!"; } var writer = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); var handshakeResponseResult = new ReadResult(new ReadOnlySequence <byte>(writer.ToArray()), false, false); _pipe = new TestDuplexPipe(); _pipe.AddReadResult(new ValueTask <ReadResult>(handshakeResponseResult)); } finally { MemoryBufferWriter.Return(writer); } _nextReadTcs = new TaskCompletionSource <ReadResult>(); _pipe.AddReadResult(new ValueTask <ReadResult>(_nextReadTcs.Task)); IHubProtocol hubProtocol; var hubConnectionBuilder = new HubConnectionBuilder(); if (Protocol == "json") { hubProtocol = new NewtonsoftJsonHubProtocol(); } else { hubProtocol = new MessagePackHubProtocol(); } hubConnectionBuilder.Services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IHubProtocol), hubProtocol)); hubConnectionBuilder.WithUrl("http://doesntmatter"); _invocationMessageBytes = hubProtocol.GetMessageBytes(new InvocationMessage(MethodName, arguments)); var delegateConnectionFactory = new DelegateConnectionFactory(endPoint => { var connection = new DefaultConnectionContext(); // prevents keep alive time being activated connection.Features.Set <IConnectionInherentKeepAliveFeature>(new TestConnectionInherentKeepAliveFeature()); connection.Transport = _pipe; return(new ValueTask <ConnectionContext>(connection)); }); hubConnectionBuilder.Services.AddSingleton <IConnectionFactory>(delegateConnectionFactory); _hubConnection = hubConnectionBuilder.Build(); _hubConnection.On(MethodName, arguments.Select(v => v.GetType()).ToArray(), OnInvoke); _hubConnection.StartAsync().GetAwaiter().GetResult(); }
public async Task TestServiceConnectionForMigratedIn() { var factory = new TestClientConnectionFactory(); var connection = MockServiceConnection(null, factory); // create a connection with migration header. await connection.OnClientConnectedAsyncForTest(new OpenConnectionMessage("foo", new Claim[0]) { Headers = new Dictionary <string, StringValues> { { Constants.AsrsMigrateFrom, "another-server" } } }); Assert.Equal(1, factory.Connections.Count); var context = factory.Connections[0]; Assert.True(context.IsMigrated); var message = new AspNetCore.SignalR.Protocol.HandshakeResponseMessage(""); HandshakeProtocol.WriteResponseMessage(message, context.Transport.Output); await context.Transport.Output.FlushAsync(); var task = context.Transport.Input.ReadAsync(); await Task.Delay(100); // nothing should be written into the transport Assert.False(task.IsCompleted); Assert.True(context.IsMigrated); var feature = context.Features.Get <IConnectionMigrationFeature>(); Assert.NotNull(feature); Assert.Equal("another-server", feature.MigrateFrom); }
private static async Task ProvideServerHandshake(PipeReader reader, PipeWriter writer, CancellationToken cancellationToken) { bool isHandshakeCompleted = false; while (!isHandshakeCompleted) { var result = await reader.ReadAsync(cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { break; } var buffer = result.Buffer; if (HandshakeProtocol.TryParseRequestMessage(ref buffer, out var requestMessage)) { var responseMessage = HandshakeResponseMessage.Empty; if (requestMessage.Protocol != nameof(MessageStoreHubProtocol)) { responseMessage = new HandshakeResponseMessage($"Protocol '{requestMessage.Protocol}' is not supported."); } reader.AdvanceTo(buffer.Start, buffer.Start); HandshakeProtocol.WriteResponseMessage(responseMessage, writer); await writer.FlushAsync(cancellationToken).ConfigureAwait(false); isHandshakeCompleted = true; }
public void GlobalSetup() { var memoryBufferWriter = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteRequestMessage(new HandshakeRequestMessage("json", 1), memoryBufferWriter); _handshakeRequestResult = new ReadResult(new ReadOnlySequence <byte>(memoryBufferWriter.ToArray()), false, false); } finally { MemoryBufferWriter.Return(memoryBufferWriter); } _pipe = new TestDuplexPipe(); var connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), _pipe, _pipe); _hubConnectionContext = new HubConnectionContext(connection, Timeout.InfiniteTimeSpan, NullLoggerFactory.Instance); _successHubProtocolResolver = new TestHubProtocolResolver(new JsonHubProtocol()); _failureHubProtocolResolver = new TestHubProtocolResolver(null); _userIdProvider = new TestUserIdProvider(); _supportedProtocols = new List <string> { "json" }; }
public void ParsingHandshakeResponseMessageSuccessForValidMessages(string json, string error) { var message = Encoding.UTF8.GetBytes(json); var response = HandshakeProtocol.ParseResponseMessage(message); Assert.Equal(error, response.Error); }
public void ParsingHandshakeRequestMessageSuccessForValidMessages(string json, string protocol) { var message = Encoding.UTF8.GetBytes(json); Assert.True(HandshakeProtocol.TryParseRequestMessage(new ReadOnlySequence <byte>(message), out var deserializedMessage, out _, out _)); Assert.Equal(protocol, deserializedMessage.Protocol); }
static HubConnectionContext() { using (var memoryBufferWriter = new MemoryBufferWriter()) { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, memoryBufferWriter); _successHandshakeResponseData = memoryBufferWriter.ToArray(); } }
public void ParsingHandshakeResponseMessageThrowsForInvalidMessages(string payload, string expectedMessage) { var message = Encoding.UTF8.GetBytes(payload); var exception = Assert.Throws <InvalidDataException>(() => HandshakeProtocol.ParseResponseMessage(message)); Assert.Equal(expectedMessage, exception.Message); }
public void ParsingHandshakeRequestMessageThrowsForInvalidMessages(string payload, string expectedMessage) { var message = new ReadOnlySequence <byte>(Encoding.UTF8.GetBytes(payload)); var exception = Assert.Throws <InvalidDataException>(() => Assert.True(HandshakeProtocol.TryParseRequestMessage(ref message, out _))); Assert.Equal(expectedMessage, exception.Message); }
public void GlobalSetup() { var writer = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); var handshakeResponseResult = new ReadResult(new ReadOnlySequence <byte>(writer.ToArray()), false, false); _pipe = new TestDuplexPipe(); _pipe.AddReadResult(new ValueTask <ReadResult>(handshakeResponseResult)); } finally { MemoryBufferWriter.Return(writer); } _tcs = new TaskCompletionSource <ReadResult>(); _pipe.AddReadResult(new ValueTask <ReadResult>(_tcs.Task)); var hubConnectionBuilder = new HubConnectionBuilder(); if (Protocol == "json") { // JSON protocol added by default } else { hubConnectionBuilder.AddMessagePackProtocol(); } var delegateConnectionFactory = new DelegateConnectionFactory(format => { var connection = new DefaultConnectionContext(); // prevents keep alive time being activated connection.Features.Set <IConnectionInherentKeepAliveFeature>(new TestConnectionInherentKeepAliveFeature()); connection.Transport = _pipe; return(Task.FromResult <ConnectionContext>(connection)); }, connection => { connection.Transport.Output.Complete(); connection.Transport.Input.Complete(); return(Task.CompletedTask); }); hubConnectionBuilder.Services.AddSingleton <IConnectionFactory>(delegateConnectionFactory); _hubConnection = hubConnectionBuilder.Build(); _hubConnection.StartAsync().GetAwaiter().GetResult(); _arguments = new object[ArgumentCount]; for (var i = 0; i < _arguments.Length; i++) { _arguments[i] = "Hello world!"; } }
public async Task ReadHandshakeAndSendResponseAsync() { await SentMessages.ReadAsync(); var output = new MemoryStream(); HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, output); await _receivedMessages.Writer.WriteAsync(output.ToArray()); }
public async Task <string> ReadHandshakeAndSendResponseAsync() { var s = await ReadSentTextMessageAsync(); using (var output = new MemoryBufferWriter()) { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, output); await Application.Output.WriteAsync(output.ToArray()); } return(s); }
public void HandShakeWriteResponseEmpty_MemoryBufferWriter() { var writer = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); } finally { MemoryBufferWriter.Return(writer); } }
public void HandShakeWriteRequest_MemoryBufferWriter() { var memoryBufferWriter = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteRequestMessage(new HandshakeRequestMessage("json", 1), memoryBufferWriter); } finally { MemoryBufferWriter.Return(memoryBufferWriter); } }
/// <summary> /// WebSocket 接收到消息的处理时间 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void WebSocket_MessageReceived(object sender, MessageReceivedEventArgs e) { var data = e.Message; Log.Debug($"收到服务端消息:{data}"); if (data.Length < 1) { return; //非 signalR 协议中的返回 } data = data.Substring(0, data.Length - 1); var separator = new byte[1] { 0x1e }; var separatorStr = Encoding.UTF8.GetString(separator); var messages = data.Split(separatorStr[0]); if (messages == null || messages.Length <= 0) { Log.Debug("收到的服务端消息未解析到有用信息"); return; } foreach (var message in messages) { try { if (!string.IsNullOrEmpty(message)) { bool isHandshakeResponse = HandshakeProtocol .TryParseHandshakeResponseMessage(message, out HandshakeResponseMessage handshakeResponseMessage); Log.Debug($"SuccessfulHandshake={SuccessfulHandshake}, TryParseHandshakeResponseMessage={isHandshakeResponse}"); if (SuccessfulHandshake && !isHandshakeResponse) { if (ReceiveMessageLoop != null) { ReceiveMessageLoop.BeginInvoke(message, null, null); } } else if (!SuccessfulHandshake && isHandshakeResponse) { SuccessfulHandshake = true; HandshakeMessage = handshakeResponseMessage; } } } catch (Exception e1) { Log.Error("WebSocket 处理消息出错", e1); continue; } } }
public HubMessage TryRead(bool isHandshake = false) { if (_messages.Count > 0) { return(_messages.Dequeue()); } if (!Connection.Application.Input.TryRead(out var result)) { return(null); } var buffer = result.Buffer; var consumed = buffer.End; var examined = consumed; try { if (!isHandshake) { var messages = new List <HubMessage>(); if (_protocol.TryParseMessages(result.Buffer.ToArray(), _invocationBinder, messages)) { foreach (var m in messages) { _messages.Enqueue(m); } return(_messages.Dequeue()); } } else { HandshakeProtocol.TryReadMessageIntoSingleMemory(buffer, out consumed, out examined, out var data); // read first message out of the incoming data if (!TextMessageParser.TryParseMessage(ref data, out var payload)) { throw new InvalidDataException("Unable to parse payload as a handshake response message."); } return(HandshakeProtocol.ParseResponseMessage(payload)); } } finally { Connection.Application.Input.AdvanceTo(consumed, examined); } return(null); }
static HubConnectionContext() { var memoryBufferWriter = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, memoryBufferWriter); _successHandshakeResponseData = memoryBufferWriter.ToArray(); } finally { MemoryBufferWriter.Return(memoryBufferWriter); } }
public void HandShakeWriteResponse_MemoryBufferWriter() { ReadOnlyMemory <byte> result; var memoryBufferWriter = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, memoryBufferWriter); result = memoryBufferWriter.ToArray(); } finally { MemoryBufferWriter.Return(memoryBufferWriter); } }
public async Task <string> ReadHandshakeAndSendResponseAsync() { var s = await ReadSentTextMessageAsync(); var output = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, output); await Application.Output.WriteAsync(output.ToArray()); } finally { MemoryBufferWriter.Return(output); } return(s); }
public void GlobalSetup() { using (var writer = new MemoryBufferWriter()) { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); _handshakeResponseResult = new ReadResult(new ReadOnlySequence <byte>(writer.ToArray()), false, false); } _pipe = new TestDuplexPipe(); var connection = new TestConnection(); // prevents keep alive time being activated connection.Features.Set <IConnectionInherentKeepAliveFeature>(new TestConnectionInherentKeepAliveFeature()); connection.Transport = _pipe; _hubConnection = new HubConnection(() => connection, new JsonHubProtocol(), new NullLoggerFactory()); }
public void GlobalSetup() { var writer = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); var handshakeResponseResult = new ReadResult(new ReadOnlySequence <byte>(writer.ToArray()), false, false); _pipe = new TestDuplexPipe(); _pipe.AddReadResult(new ValueTask <ReadResult>(handshakeResponseResult)); } finally { MemoryBufferWriter.Return(writer); } _tcs = new TaskCompletionSource <ReadResult>(); _pipe.AddReadResult(new ValueTask <ReadResult>(_tcs.Task)); var protocol = Protocol == "json" ? (IHubProtocol) new JsonHubProtocol() : new MessagePackHubProtocol(); var hubConnectionBuilder = new HubConnectionBuilder(); hubConnectionBuilder.WithHubProtocol(protocol); hubConnectionBuilder.WithConnectionFactory(format => { var connection = new DefaultConnectionContext(); // prevents keep alive time being activated connection.Features.Set <IConnectionInherentKeepAliveFeature>(new TestConnectionInherentKeepAliveFeature()); connection.Transport = _pipe; return(Task.FromResult <ConnectionContext>(connection)); }); _hubConnection = hubConnectionBuilder.Build(); _hubConnection.StartAsync().GetAwaiter().GetResult(); _arguments = new object[ArgumentCount]; for (var i = 0; i < _arguments.Length; i++) { _arguments[i] = "Hello world!"; } }
private async Task StartAsyncCore() { await _connection.StartAsync(_protocol.TransferFormat); _needKeepAlive = _connection.Features.Get <IConnectionInherentKeepAliveFeature>() == null; _receivedHandshakeResponse = false; Log.HubProtocol(_logger, _protocol.Name); _connectionActive = new CancellationTokenSource(); using (var memoryStream = new MemoryStream()) { Log.SendingHubHandshake(_logger); HandshakeProtocol.WriteRequestMessage(new HandshakeRequestMessage(_protocol.Name), memoryStream); await _connection.SendAsync(memoryStream.ToArray(), _connectionActive.Token); } ResetTimeoutTimer(); }
public async Task <string> ReadHandshakeAndSendResponseAsync(int minorVersion = 0) { var s = await ReadSentTextMessageAsync(); byte[] response; var output = MemoryBufferWriter.Get(); try { HandshakeProtocol.WriteResponseMessage(new HandshakeResponseMessage(minorVersion), output); response = output.ToArray(); } finally { MemoryBufferWriter.Return(output); } await Application.Output.WriteAsync(response); return(s); }
public async ValueTask <ConnectionContext> ConnectAsync(EndPoint endpoint, CancellationToken cancellationToken = default) { if (!(endpoint is AzureSignalREndPoint azEndpoint)) { throw new NotSupportedException($"{endpoint} is not supported"); } var options = new HttpConnectionOptions { Url = azEndpoint.Uri, Transports = HttpTransportType.WebSockets, SkipNegotiation = true }; options.Headers["Authorization"] = $"Bearer {azEndpoint.AccessToken}"; var httpConnection = new HttpConnection(options, _loggerFactory); await httpConnection.StartAsync(); // The SignalR service expects the handshake in default mode, this isn't relevant when using it like a byte stream HandshakeProtocol.WriteRequestMessage(new HandshakeRequestMessage("unknown", 1), httpConnection.Transport.Output); await httpConnection.Transport.Output.FlushAsync(); return(httpConnection); }