예제 #1
0
        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();
        }
예제 #2
0
 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);
     });
 }
예제 #3
0
        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();
        }