/// <summary> /// Handles an incoming handshake request. We should only receive one of these! /// </summary> protected async Task handleHandshakeRequestMessage(HandshakeRequestMessage message) { CurrentViewPort = message.InitialViewport; AbsoluteCursorPosition = message.InitialAbsCursorPosition; // Tell everyone else about the new client ClientStatesMessage newClientNotification = new ClientStatesMessage(); newClientNotification.ClientStates.Add(GenerateStateSnapshot()); await manager.Broadcast(this, newClientNotification); // Send the new client a response to their handshake request HandshakeResponseMessage handshakeResponse = new HandshakeResponseMessage(); handshakeResponse.Id = Id; handshakeResponse.Colour = Colour; handshakeResponse.Name = Name; foreach (Plane plane in manager.NibriServer.PlaneManager.Planes) { handshakeResponse.Planes.Add(plane.Name); } await Send(handshakeResponse); // Tell the new client about everyone else who's connected // FUTURE: If we need to handle a large number of connections, we should generate this message based on the chunks surrounding the client await Send(GenerateClientStateUpdate()); }
private void ProcessHandhakeRequest(HandshakeRequestMessage request) { if (Sender != Self) { Sender.Tell(new HandshakeResponseMessage(request.Location)); } }
private async Task <HandshakeResponseMessage> Handshake() { var message = new HandshakeRequestMessage(supportedConnectionTypes: new[] { ONLY_SUPPORTED_CONNECTION_TYPE }, id: MessageCounter++); HandshakeResponseMessage result; try { result = await ExecuteSynchronousMessage <HandshakeResponseMessage>(message, HandshakeTimeout); } catch (TimeoutException) { throw new HandshakeException(HandshakeTimeout); } if (!result.Successful) { throw new HandshakeException(result.Error); } if (result.SupportedConnectionTypes.Contains(ONLY_SUPPORTED_CONNECTION_TYPE)) { return(result); } var flatTypes = result .SupportedConnectionTypes .Select(ct => "'" + ct + "'") .Aggregate((c1, c2) => c1 + "," + c2); var error = string.Format(CONNECTION_TYPE_ERROR_FORMAT, flatTypes); throw new HandshakeException(error); }
public ServiceConnectionBase(IServiceProtocol serviceProtocol, ILogger logger, string connectionId) { ServiceProtocol = serviceProtocol; _logger = logger; _connectionId = connectionId; _cachedPingBytes = serviceProtocol.GetMessageBytes(PingMessage.Instance); _handshakeRequest = new HandshakeRequestMessage(serviceProtocol.Version); }
public AzureSignalRDispatcher(Uri uri, string token, ILoggerFactory loggerFactory) { _uri = uri; _token = token; _loggerFactory = loggerFactory; Logger = loggerFactory.CreateLogger <AzureSignalRDispatcher>(); _cachedPingBytes = ServiceProtocol.GetMessageBytes(PingMessage.Instance); _handshakeRequest = new HandshakeRequestMessage(ServiceProtocol.Version); }
public ServiceConnectionBase(IServiceProtocol serviceProtocol, ILoggerFactory loggerFactory, string connectionId, IServiceConnectionManager serviceConnectionManager, ServerConnectionType connectionType) { ServiceProtocol = serviceProtocol; ConnectionId = connectionId; _connectionType = connectionType; _cachedPingBytes = serviceProtocol.GetMessageBytes(PingMessage.Instance); _handshakeRequest = new HandshakeRequestMessage(serviceProtocol.Version, (int)connectionType); _logger = loggerFactory?.CreateLogger <ServiceConnectionBase>() ?? NullLogger <ServiceConnectionBase> .Instance; _serviceConnectionManager = serviceConnectionManager; }
/// <summary> /// Writes the serialized representation of a <see cref="HandshakeRequestMessage"/> to the specified writer. /// </summary> /// <param name="requestMessage">The message to write.</param> /// <param name="output">The output writer.</param> public static void WriteRequestMessage(HandshakeRequestMessage requestMessage, IBufferWriter <byte> output) { var reusableWriter = ReusableUtf8JsonWriter.Get(output); try { var writer = reusableWriter.GetJsonWriter(); writer.WriteStartObject(); writer.WriteString(ProtocolPropertyNameBytes, requestMessage.Protocol); writer.WriteNumber(ProtocolVersionPropertyNameBytes, requestMessage.Version); writer.WriteEndObject(); writer.Flush(); Debug.Assert(writer.CurrentDepth == 0); } finally { ReusableUtf8JsonWriter.Return(reusableWriter); } TextMessageFormatter.WriteRecordSeparator(output); }
/// <summary> /// 与服务器进行 Handshake /// </summary> private void Handshake() { // Send the Handshake request Log.Debug("Sending Hub Handshake"); try { var handshakeRequest = new HandshakeRequestMessage(_protocol.Name, _protocol.Version); SendHubMessage(handshakeRequest); bool isSuccessfulHandshake = false; double count = HandshakeTimeout.TotalSeconds; while (count-- > 0) { if (_connection.Transport.SuccessfulHandshake) { if (_connection.Transport.HandshakeMessage.Error != null) { Log.Debug("Handshake Server Error"); throw new Exception( $"Unable to complete handshake with the server due to an error: {_connection.Transport.HandshakeMessage.Error}"); } isSuccessfulHandshake = true; break; } Thread.Sleep(1000); } if (!isSuccessfulHandshake) { throw new TimeoutException("Handshake Timeout"); } } catch (Exception e) { Log.Error("Error Receiving Handshake Response", e); throw e; } Log.Debug("Handshake Complete"); }
public void Login(long userId, string userToken) { var handshake = new HandshakeRequestMessage { AppStore = 2, Build = 709, DeviceType = 2, Hash = "2f2c3464104feb771097b42ebf4dfe871bd56062", KeyVersion = 20, MajorVersion = 8, MinorVersion = 0, Protocol = 1, }; _lrMessage = new LoginRequestMessage { // To make a new account UserId = userId, UserToken = userToken, MajorVersion = 8, MinorVersion = 709, ContentVersion = 0, LocaleKey = 2000000, Language = "en", AdvertisingGuid = "", OSVersion = "4.4.2", IsAdvertisingTrackingEnabled = true, MasterHash = "2f2c3464104feb771097b42ebf4dfe871bd56062", FacebookDistributionID = "", VendorGUID = "", ClientVersion = "8.709.2", Seed = new Random().Next() }; _networkManager.SendMessage(handshake); _state = 1; }
private bool HandshakeRequestMessagesEqual(HandshakeRequestMessage x, HandshakeRequestMessage y) { return(x.Version == y.Version); }
private async Task HandshakeAsync(ConnectionState startingConnectionState, CancellationToken cancellationToken) { // Send the Handshake request Log.SendingHubHandshake(_logger); var handshakeRequest = new HandshakeRequestMessage(_protocol.Name, _protocol.Version); HandshakeProtocol.WriteRequestMessage(handshakeRequest, startingConnectionState.Connection.Transport.Output); var sendHandshakeResult = await startingConnectionState.Connection.Transport.Output.FlushAsync(CancellationToken.None); if (sendHandshakeResult.IsCompleted) { // The other side disconnected throw new InvalidOperationException("The server disconnected before the handshake was completed"); } try { using (var handshakeCts = new CancellationTokenSource(HandshakeTimeout)) using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, handshakeCts.Token)) { while (true) { var result = await startingConnectionState.Connection.Transport.Input.ReadAsync(cts.Token); var buffer = result.Buffer; var consumed = buffer.Start; var examined = buffer.End; try { // Read first message out of the incoming data if (!buffer.IsEmpty) { if (HandshakeProtocol.TryParseResponseMessage(ref buffer, out var message)) { // Adjust consumed and examined to point to the end of the handshake // response, this handles the case where invocations are sent in the same payload // as the the negotiate response. consumed = buffer.Start; examined = consumed; if (message.Error != null) { Log.HandshakeServerError(_logger, message.Error); throw new HubException( $"Unable to complete handshake with the server due to an error: {message.Error}"); } break; } } else if (result.IsCompleted) { // Not enough data, and we won't be getting any more data. throw new InvalidOperationException( "The server disconnected before sending a handshake response"); } } finally { startingConnectionState.Connection.Transport.Input.AdvanceTo(consumed, examined); } } } } // Ignore HubException because we throw it when we receive a handshake response with an error // And we don't need to log that the handshake failed catch (Exception ex) when(!(ex is HubException)) { // shutdown if we're unable to read handshake Log.ErrorReceivingHandshakeResponse(_logger, ex); throw; } Log.HandshakeComplete(_logger); }
/// <summary> /// Creates a new <see cref="HandshakeRequestMessage"/> from the specified serialized representation. /// </summary> /// <param name="buffer">The serialized representation of the message.</param> /// <param name="requestMessage">When this method returns, contains the parsed message.</param> /// <returns>A value that is <c>true</c> if the <see cref="HandshakeRequestMessage"/> was successfully parsed; otherwise, <c>false</c>.</returns> public static bool TryParseRequestMessage(ref ReadOnlySequence <byte> buffer, [NotNullWhen(true)] out HandshakeRequestMessage?requestMessage) { if (!TextMessageParser.TryParseMessage(ref buffer, out var payload)) { requestMessage = null; return(false); } var reader = new Utf8JsonReader(payload, isFinalBlock: true, state: default); reader.CheckRead(); reader.EnsureObjectStart(); string?protocol = null; int? protocolVersion = null; while (reader.CheckRead()) { if (reader.TokenType == JsonTokenType.PropertyName) { if (reader.ValueTextEquals(ProtocolPropertyNameBytes.EncodedUtf8Bytes)) { protocol = reader.ReadAsString(ProtocolPropertyName); } else if (reader.ValueTextEquals(ProtocolVersionPropertyNameBytes.EncodedUtf8Bytes)) { protocolVersion = reader.ReadAsInt32(ProtocolVersionPropertyName); } else { reader.Skip(); } } else if (reader.TokenType == JsonTokenType.EndObject) { break; } else { throw new InvalidDataException($"Unexpected token '{reader.TokenType}' when reading handshake request JSON. Message content: {GetPayloadAsString()}"); } } if (protocol == null) { throw new InvalidDataException($"Missing required property '{ProtocolPropertyName}'. Message content: {GetPayloadAsString()}"); } if (protocolVersion == null) { throw new InvalidDataException($"Missing required property '{ProtocolVersionPropertyName}'. Message content: {GetPayloadAsString()}"); } requestMessage = new HandshakeRequestMessage(protocol, protocolVersion.Value); // For error messages, we want to print the payload as text string GetPayloadAsString() { // REVIEW: Should we show hex for binary charaters? return(Encoding.UTF8.GetString(payload.ToArray())); } return(true); }