private void HandleDisconnect() { LogManager.Instance.Add("Client has disconnected. Server might have shutdown.", LogLevel.Medium); ServerDisconnect?.Invoke(); Dispose(); TryConnect(); }
/// <summary> /// 通知断线 /// </summary> public void NotifyDisconnection() { try { ServerDisconnect?.Invoke(); } catch (Exception ex) { throw ex; } }
public async Task DisconnectAsync() { if (!Connected) { return; } _connector.MessageReceived -= MessageReceivedHandler; await _connector.DisconnectAsync().ConfigureAwait(false); ServerDisconnect?.Invoke(this, new EventArgs()); }
/// <summary> /// Initializes a new instance of the <see cref="ButtplugClient"/> class. /// </summary> /// <param name="aClientName">The name of the client (used by the server for UI and permissions).</param> /// <param name="aConnector">Connector for the client.</param> public ButtplugClient([NotNull] string aClientName, [NotNull] IButtplugClientConnector aConnector) { ButtplugUtils.ArgumentNotNull(aConnector, nameof(aConnector)); Name = aClientName; _connector = aConnector; _connector.Disconnected += (aObj, aEventArgs) => { ServerDisconnect?.Invoke(aObj, aEventArgs); }; _connector.InvalidMessageReceived += ConnectorErrorHandler; _bpLogManager = new ButtplugLogManager(); _connector.LogManager = _bpLogManager; _bpLogger = _bpLogManager.GetLogger(GetType()); _bpLogger.Info("Finished setting up ButtplugClient"); }
public void SorterCallback(UIntPtr buf, int buf_length) { Span <byte> byteArray; unsafe { byteArray = new Span <byte>(buf.ToPointer(), buf_length); } var server_message = ButtplugFFIServerMessage.Parser.ParseFrom(byteArray.ToArray()); if (server_message.Id > 0) { _messageSorter.CheckMessage(server_message); } else if (server_message.Message.MsgCase == ButtplugFFIServerMessage.Types.FFIMessage.MsgOneofCase.ServerMessage) { if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.DeviceAdded) { var device_added_message = server_message.Message.ServerMessage.DeviceAdded; var device_handle = ButtplugFFI.SendCreateDevice(_clientHandle, device_added_message.Index); var attribute_dict = new Dictionary <ServerMessage.Types.MessageAttributeType, ButtplugMessageAttributes>(); for (var i = 0; i < device_added_message.MessageAttributes.Count; ++i) { var attributes = device_added_message.MessageAttributes[i]; var device_message_attributes = new ButtplugMessageAttributes(attributes.FeatureCount, attributes.StepCount.ToArray(), attributes.Endpoints.ToArray(), attributes.MaxDuration.ToArray(), null, null); attribute_dict.Add(attributes.MessageType, device_message_attributes); } var device = new ButtplugClientDevice(_messageSorter, device_handle, device_added_message.Index, device_added_message.Name, attribute_dict); _devices.Add(device_added_message.Index, device); DeviceAdded.Invoke(this, new DeviceAddedEventArgs(device)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.DeviceRemoved) { var device_removed_message = server_message.Message.ServerMessage.DeviceRemoved; var device = _devices[device_removed_message.Index]; _devices.Remove(device_removed_message.Index); DeviceRemoved.Invoke(this, new DeviceRemovedEventArgs(device)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.Disconnect) { Connected = false; ServerDisconnect?.Invoke(this, null); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.Error) { var errorMsg = server_message.Message.ServerMessage.Error; var error = ButtplugException.FromError(errorMsg); if (error is ButtplugPingException) { PingTimeout?.Invoke(this, null); } ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(error)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.ScanningFinished) { ScanningFinished?.Invoke(this, null); } else { // We should probably do something here with unhandled events, but I'm not particularly sure what. I miss pattern matching. :( } } else { // We should probably do something here with unhandled events, but I'm not particularly sure what. I miss pattern matching. :( } }
protected void SorterCallbackHandler(IntPtr buf, int buf_length) { // Process the data BEFORE we throw to the C# executor, otherwise // Rust will clean up the memory and we'll have nothing to read // from, meaning a null message at best and a crash at worst. Span <byte> byteArray; unsafe { byteArray = new Span <byte>(buf.ToPointer(), buf_length); } var server_message = ButtplugFFIServerMessage.Parser.ParseFrom(byteArray.ToArray()); // Run the response in the context of the C# executor, not the Rust // thread. This means that if something goes wrong we at least // aren't blocking a rust executor thread. Task.Run(() => { if (server_message.Id > 0) { _messageSorter.CheckMessage(server_message); } else if (server_message.Message.MsgCase == ButtplugFFIServerMessage.Types.FFIMessage.MsgOneofCase.ServerMessage) { if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.DeviceAdded) { var device_added_message = server_message.Message.ServerMessage.DeviceAdded; if (_devices.ContainsKey(device_added_message.Index)) { ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(new ButtplugDeviceException("A duplicate device index was received. This is most likely a bug, please file at https://github.com/buttplugio/b******g-rs-ffi"))); return; } var device_handle = ButtplugFFI.SendCreateDevice(_clientHandle, device_added_message.Index); var attribute_dict = new Dictionary <ServerMessage.Types.MessageAttributeType, ButtplugMessageAttributes>(); for (var i = 0; i < device_added_message.MessageAttributes.Count; ++i) { var attributes = device_added_message.MessageAttributes[i]; var device_message_attributes = new ButtplugMessageAttributes(attributes.FeatureCount, attributes.StepCount.ToArray(), attributes.Endpoints.ToArray(), attributes.MaxDuration.ToArray(), null, null); attribute_dict.Add(attributes.MessageType, device_message_attributes); } var device = new ButtplugClientDevice(_messageSorter, device_handle, device_added_message.Index, device_added_message.Name, attribute_dict, SorterCallbackDelegate, GCHandle.ToIntPtr(_indexHandle)); _devices.Add(device_added_message.Index, device); DeviceAdded?.Invoke(this, new DeviceAddedEventArgs(device)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.DeviceRemoved) { var device_removed_message = server_message.Message.ServerMessage.DeviceRemoved; if (!_devices.ContainsKey(device_removed_message.Index)) { // Device was removed from our dict before we could remove it ourselves. return; } try { var device = _devices[device_removed_message.Index]; _devices.Remove(device_removed_message.Index); DeviceRemoved?.Invoke(this, new DeviceRemovedEventArgs(device)); } catch (KeyNotFoundException) { ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(new ButtplugDeviceException($"Cannot remove device index {device_removed_message.Index}, device not found."))); } } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.Disconnect) { Connected = false; _devices.Clear(); ServerDisconnect?.Invoke(this, null); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.Error) { var errorMsg = server_message.Message.ServerMessage.Error; var error = ButtplugException.FromError(errorMsg); if (error is ButtplugPingException) { PingTimeout?.Invoke(this, null); } ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(error)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.ScanningFinished) { IsScanning = false; ScanningFinished?.Invoke(this, null); } else { // We should probably do something here with unhandled events, but I'm not particularly sure what. I miss pattern matching. :( } } else { // We should probably do something here with unhandled events, but I'm not particularly sure what. I miss pattern matching. :( } }); }
private void InvokeServerDisconnectEvent() { ServerDisconnect?.Invoke(this, EventArgs.Empty); }