public async Task TestConnectionAcceptedEvent() { // There's a good chance the server will fire ConnectionAccepted while we're calling // ConnectAsync(), but using a semaphore means we'll pass even if its out of sync. var sem = new SemaphoreSlim(0, 1); _server.ConnectionAccepted += (aObject, aEventArgs) => { sem.Release(); }; await _server.StartServerAsync(() => new ButtplugServer("Test Server", 0)); sem.CurrentCount.Should().Be(0); await _client.ConnectAsync(); await sem.WaitAsync(); }
public async Task OneTimeSetUp() { _logMgr = new ButtplugLogManager(); _subtypeMgr = new TestDeviceSubtypeManager(new TestDevice(_logMgr, "Test Device")); _websocketServer = new ButtplugWebsocketServer(); await _websocketServer.StartServerAsync(() => { var server = new TestServer(); server.AddDeviceSubtypeManager(aLogger => _subtypeMgr); return(server); }); }
public void RunServer(Options aOptions) { if (aOptions.Version) { Console.WriteLine("1"); return; } _useProtobufOutput = aOptions.FrontendPipe; if (_useProtobufOutput) { _stdioTask = new Task(ReadStdio); _stdioTask.Start(); } if (aOptions.GenerateCertificate) { // CertUtils.GenerateSelfSignedCert(aOptions.CertFile, aOptions.PrivFile); Console.WriteLine("Cannot currently generate certificates."); return; } if (aOptions.DeviceConfigFile != null) { DeviceConfigurationManager.LoadBaseConfigurationFile(aOptions.DeviceConfigFile); } else { DeviceConfigurationManager.LoadBaseConfigurationFromResource(); } if (aOptions.UserDeviceConfigFile != null) { DeviceConfigurationManager.Manager.LoadUserConfigurationFile(aOptions.UserDeviceConfigFile); } if (aOptions.WebsocketServerInsecurePort == 0 && aOptions.WebsocketServerSecurePort == 0 && !aOptions.UseIpcServer) { PrintProcessLog("ERROR: Must specify either IPC server or Websocket server!"); return; } var logLevel = ButtplugLogLevel.Off; if (aOptions.Log != null) { if (!Enum.TryParse(aOptions.Log, out logLevel)) { PrintProcessLog("ERROR: Invalid log level!"); return; } } ButtplugServer ServerFactory() { var server = new CLIServer(aOptions.ServerName, (uint)aOptions.PingTime, _deviceManager); // Pull out the device manager for reuse later. if (_deviceManager == null) { _deviceManager = server.DeviceManager; } if (logLevel != ButtplugLogLevel.Off) { server.LogManager.AddLogListener(logLevel, (aLogMsg) => { PrintProcessLog(aLogMsg.LogMessage); }); } server.ClientConnected += (aObj, aEvent) => { if (_useProtobufOutput) { SendProcessMessage(new ServerProcessMessage { ClientConnected = new ServerProcessMessage.Types.ClientConnected { ClientName = server.ClientName } }); } else { Console.WriteLine($"Client connected: {server.ClientName}"); } }; return(server); } ButtplugIPCServer ipcServer = null; ButtplugWebsocketServer insecureWebsocketServer = null; ButtplugWebsocketServer secureWebsocketServer = null; if (aOptions.WebsocketServerInsecurePort != 0) { insecureWebsocketServer = new ButtplugWebsocketServer(); insecureWebsocketServer.StartServerAsync(ServerFactory, 1, aOptions.WebsocketServerInsecurePort, !aOptions.WebsocketServerAllInterfaces).Wait(); insecureWebsocketServer.ConnectionClosed += (aSender, aArgs) => { _disconnectWait.SetResult(true); }; PrintProcessLog("Insecure websocket Server now running..."); } if (aOptions.WebsocketServerSecurePort != 0 && aOptions.CertFile != null && aOptions.PrivFile != null) { secureWebsocketServer = new ButtplugWebsocketServer(); secureWebsocketServer.StartServerAsync(ServerFactory, 1, aOptions.WebsocketServerSecurePort, !aOptions.WebsocketServerAllInterfaces, aOptions.CertFile, aOptions.PrivFile).Wait(); secureWebsocketServer.ConnectionClosed += (aSender, aArgs) => { _disconnectWait.SetResult(true); }; PrintProcessLog("Secure websocket Server now running..."); } if (aOptions.UseIpcServer) { ipcServer = new ButtplugIPCServer(); ipcServer.StartServer(ServerFactory, aOptions.IpcPipe); ipcServer.ConnectionClosed += (aSender, aArgs) => { _disconnectWait.SetResult(true); }; PrintProcessLog("IPC Server now running..."); } // Now that all server possibilities are up and running, if we have a pipe, let the // parent program know we've started. if (_useProtobufOutput) { var msg = new ServerProcessMessage { ProcessStarted = new ServerProcessMessage.Types.ProcessStarted() }; SendProcessMessage(msg); } else { Console.WriteLine("Server started, waiting for client connection."); } do { _disconnectWait.Task.Wait(); if (ipcServer != null && ipcServer.Connected) { ipcServer?.Disconnect(); } if (insecureWebsocketServer != null && insecureWebsocketServer.Connected) { insecureWebsocketServer?.DisconnectAsync().Wait(); } if (secureWebsocketServer != null && secureWebsocketServer.Connected) { secureWebsocketServer?.DisconnectAsync().Wait(); } if (_useProtobufOutput) { var msg = new ServerProcessMessage { ClientDisconnected = new ServerProcessMessage.Types.ClientDisconnected() }; SendProcessMessage(msg); } else { Console.WriteLine("Client disconnected."); } _disconnectWait = new TaskCompletionSource <bool>(); } while (aOptions.StayOpen && !_shouldExit); if (!_useProtobufOutput) { return; } PrintProcessLog("Exiting"); if (_useProtobufOutput) { var exitMsg = new ServerProcessMessage { ProcessEnded = new ServerProcessMessage.Types.ProcessEnded() }; SendProcessMessage(exitMsg); } _stdinTokenSource.Cancel(); }