/// <summary> /// Collects changes in the profile, and sends them to client after delay /// </summary> /// <param name="profile"></param> /// <param name="delay"></param> /// <returns></returns> private async void SendUpdatesToClient(ObservableServerProfile profile, float delay) { // Wait for the delay await Task.Delay(Mathf.RoundToInt(delay < 0.01f ? 0.01f : delay * 1000)); if (profile.ClientPeer == null || !profile.ClientPeer.IsConnected) { // If client is not connected, and we don't need to send him profile updates profile.ClearUpdates(); return; } // Get profile updated data in bytes var updates = profile.GetUpdates(); // Clear updated data in profile profile.ClearUpdates(); // Send these data to client profile.ClientPeer.SendMessage(MessageHelper.Create((short)MstMessageCodes.UpdateClientProfile, updates), DeliveryMethod.ReliableSequenced); await Task.Delay(10); // Remove value from debounced updates profilesToBeSentToClients.Remove(profile.Username); }
/// <summary> /// Collects changes in the profile, and sends them to client after delay /// </summary> /// <param name="profile"></param> /// <param name="delay"></param> /// <returns></returns> private async void SendUpdatesToClient(ObservableServerProfile profile, float delay) { // Wait for the delay await Task.Delay(Mathf.RoundToInt(delay < 0.01f ? 0.01f : delay * 1000)); // Remove value from debounced updates debouncedClientUpdates.Remove(profile.Username); if (profile.ClientPeer == null || !profile.ClientPeer.IsConnected) { // If client is not connected, and we don't need to send him profile updates profile.ClearUpdates(); return; } using (var ms = new MemoryStream()) { using (var writer = new EndianBinaryWriter(EndianBitConverter.Big, ms)) { profile.GetUpdates(writer); profile.ClearUpdates(); } profile.ClientPeer.SendMessage(MessageHelper.Create((short)MstMessageCodes.UpdateClientProfile, ms.ToArray()), DeliveryMethod.ReliableSequenced); } }
/// <summary> /// Sends a request to server, retrieves all profile values, and applies them to a provided /// profile /// </summary> public void FillProfileValues(ObservableServerProfile profile, SuccessCallback callback, IClientSocket connection) { if (!connection.IsConnected) { callback.Invoke(false, "Not connected"); return; } connection.SendMessage((short)MstMessageCodes.ServerProfileRequest, profile.Username, (status, response) => { if (status != ResponseStatus.Success) { callback.Invoke(false, response.AsString("Unknown error")); return; } // Use the bytes received, to replicate the profile profile.FromBytes(response.AsBytes()); profile.ClearUpdates(); _profiles[profile.Username] = profile; profile.OnModifiedInServerEvent += serverProfile => { OnProfileModified(profile, connection); }; profile.OnDisposedEvent += OnProfileDisposed; callback.Invoke(true, null); }); }
/// <summary> /// Saves a profile into database after delay /// </summary> /// <param name="profile"></param> /// <param name="delay"></param> /// <returns></returns> private async void SaveProfile(ObservableServerProfile profile, float delay) { // Wait for the delay await Task.Delay(Mathf.RoundToInt(delay < 0.01f ? 0.01f : delay * 1000)); // Remove value from debounced updates profilesToBeSaved.Remove(profile.Username); await profileDatabaseAccessor.UpdateProfileAsync(profile); }
private void OnProfileModified(ObservableServerProfile profile, IClientSocket connection) { _modifiedProfiles.Add(profile); if (_sendUpdatesCoroutine != null) { return; } _sendUpdatesCoroutine = MstTimer.Instance.StartCoroutine(KeepSendingUpdates(connection)); }
private void OnProfileModified(ObservableServerProfile profile, IClientSocket connection) { if (!modifiedProfilesList.Contains(profile)) { modifiedProfilesList.Add(profile); } if (sendUpdatesCoroutine != null) { return; } sendUpdatesCoroutine = MstTimer.Instance.StartCoroutine(KeepSendingUpdates(connection)); }
/// <summary> /// Invoked, when profile is changed /// </summary> /// <param name="profile"></param> private void OnProfileChangedEventHandler(ObservableServerProfile profile) { // Debouncing is used to reduce a number of updates per interval to one // TODO make debounce lookup more efficient than using string hashet if (!profilesToBeSaved.Contains(profile.Username) && profile.ShouldBeSavedToDatabase) { // If profile is not already waiting to be saved profilesToBeSaved.Add(profile.Username); SaveProfile(profile, saveProfileInterval); } if (!profilesToBeSentToClients.Contains(profile.Username)) { // If it's a master server profilesToBeSentToClients.Add(profile.Username); SendUpdatesToClient(profile, clientUpdateInterval); } }
/// <summary> /// Invoked, when profile is changed /// </summary> /// <param name="profile"></param> private void OnProfileChangedEventHandler(ObservableServerProfile profile) { var user = profile.ClientPeer.GetExtension <IUserPeerExtension>(); if (!user.Account.IsGuest || (user.Account.IsGuest && authModule.SaveGuestInfo)) { if (!profilesToBeSaved.Contains(profile.UserId) && profile.ShouldBeSavedToDatabase) { // If profile is not already waiting to be saved profilesToBeSaved.Add(profile.UserId); _ = SaveProfile(profile, saveProfileInterval); } } if (!profilesToBeSentToClients.Contains(profile.UserId)) { // If it's a master server profilesToBeSentToClients.Add(profile.UserId); _ = SendUpdatesToClient(profile, clientUpdateInterval); } }
public ProfilePeerExtension(ObservableServerProfile profile, IPeer peer) { Username = profile.Username; Profile = profile; Peer = peer; }
/// <summary> /// Sends a request to server, retrieves all profile values, and applies them to a provided /// profile /// </summary> public void FillProfileValues(ObservableServerProfile profile, SuccessCallback callback) { FillProfileValues(profile, callback, Connection); }
private void OnProfileDisposed(ObservableServerProfile profile) { profile.OnDisposedEvent -= OnProfileDisposed; profilesList.Remove(profile.UserId); }
private void OnProfileDisposed(ObservableServerProfile profile) { profile.OnDisposedEvent -= OnProfileDisposed; _profiles.Remove(profile.Username); }