// https://stackoverflow.com/questions/19415646/should-i-avoid-async-void-event-handlers private async void _OnClientConnectionStateChangedCallback(bool clientConnectionState) { // lock current execution context await _semaphore.WaitAsync(); // due to the peculiarities of the work of the old and new client // where the old one, in case of an unauthorized state, generates two events of changing the state of the connection at once // the first is positive, and the second, negative // while a negative one is generated after receiving the first request (which is a request to obtain data about an authorized user) // the new client, in an unauthorized state, generates only one event, negative // so the code is structured to be compatible with these two situations // to solve this problem, the concept of an internal state was introduced (there are three of them at once) // no decisions about the state of the connection will be made until the incoming state is different from the previous one if (_internalConnectionState == null || _internalConnectionState.Value != clientConnectionState) { var isAuthorized = false; // so, if we have connected to the host, this does not mean that the connection is active (for example, the user has not yet logged into the ZClient) // therefore, before we say in the affirmative that the connection has been established, we will try to get an authorized user if (clientConnectionState) { var userRequest = ZRequestFactory.CreateUserInfoRequest(); var response = await ZRouter.GetResponseAsync(userRequest); if (response.StatusCode == ZResponseStatusCode.Ok) { _currentUserInfo = _ParseUserInfo(response.ResponsePackets); _pingTimer.Start(); isAuthorized = true; } else { _logger.Warning($"Request failed {userRequest}"); } // set current connection state _internalConnectionState = isAuthorized; } else { // reset internal connection state _internalConnectionState = null; _currentUserInfo = null; _pingTimer.Stop(); } // ReSharper disable once InvertIf if (_raiseOnConnectionChangedEvent) { _RaiseOnConnectionChangedEvent(IsConnected, _currentUserInfo); _raiseOnConnectionChangedEvent = true; } } _semaphore.Release(); }
public ZUserDto Parse(ZPacket packet) { var user = new ZUserDto(); using (var memory = new MemoryStream(packet.Payload, false)) using (var binaryReader = new BinaryReader(memory, Encoding.ASCII)) { user.UserId = binaryReader.ReadZUInt32(); user.UserName = binaryReader.ReadZString(); } return(user); }
private void _RaiseOnConnectionChangedEvent(bool connectionState, ZUserDto authorizedUserDto) => ConnectionChanged?.Invoke((IZConnection)this, new ZConnectionChangedEventArgs(connectionState, authorizedUserDto));
/// <inheritdoc /> /// <summary> /// Creates an instance of <see cref="T:Zlo4NET.Api.Models.Shared.ZConnectionChangedEventArgs" /> /// </summary> public ZConnectionChangedEventArgs(bool isConnected, ZUserDto authorizedUserDto) { IsConnected = isConnected; AuthorizedUser = authorizedUserDto; }
/// <summary> /// Creates an instance of <see cref="ZAuthorizedEventArgs"/> /// </summary> public ZAuthorizedEventArgs(ZUserDto user) { AuthorizedUser = user; }