protected override async void HandleClient(SimpleSocket clientSocket, string url) { await AcceptConnection(clientSocket); var socketMessageLayer = new SocketMessageLayer(clientSocket, true); socketMessageLayer.AddPacketHandler <TestRegistrationRequest>(request => { if (request.Tester) { switch (request.Platform) { case (int)PlatformType.Windows: { Process process = null; var debugInfo = ""; try { var workingDir = Path.GetDirectoryName(request.Cmd); if (workingDir != null) { var start = new ProcessStartInfo { WorkingDirectory = workingDir, FileName = request.Cmd }; start.EnvironmentVariables["SiliconStudioXenkoDir"] = Environment.GetEnvironmentVariable("SiliconStudioXenkoDir"); start.UseShellExecute = false; start.RedirectStandardError = true; start.RedirectStandardOutput = true; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; socketMessageLayer.Send(new LogRequest { Message = debugInfo }).Wait(); process = Process.Start(start); } } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { process.OutputDataReceived += (sender, args) => { try { socketMessageLayer.Send(new LogRequest { Message = $"STDIO: {args.Data}" }).Wait(); } catch { } }; process.ErrorDataReceived += (sender, args) => { try { socketMessageLayer.Send(new LogRequest { Message = $"STDERR: {args.Data}" }).Wait(); } catch { } }; process.BeginOutputReadLine(); process.BeginErrorReadLine(); var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } case (int)PlatformType.Android: { Process process = null; try { process = Process.Start("cmd.exe", $"/C adb shell monkey -p {request.GameAssembly}.{request.GameAssembly} -c android.intent.category.LAUNCHER 1"); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Launch exception: " + ex.Message }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process." }).Wait(); } else { lock (loggerLock) { currentTester = socketMessageLayer; } var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } case (int)PlatformType.iOS: { Process process = null; var debugInfo = ""; try { Thread.Sleep(5000); //ios processes might be slow to close, we must make sure that we start clean var start = new ProcessStartInfo { WorkingDirectory = $"{Environment.GetEnvironmentVariable("SiliconStudioXenkoDir")}\\Bin\\Windows-Direct3D11\\", FileName = $"{Environment.GetEnvironmentVariable("SiliconStudioXenkoDir")}\\Bin\\Windows-Direct3D11\\idevicedebug.exe", Arguments = $"run com.your-company.{request.GameAssembly}", UseShellExecute = false }; debugInfo = "Starting process " + start.FileName + " with path " + start.WorkingDirectory; process = Process.Start(start); } catch (Exception ex) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = $"Launch exception: {ex.Message} info: {debugInfo}" }).Wait(); } if (process == null) { socketMessageLayer.Send(new StatusMessageRequest { Error = true, Message = "Failed to start game process. " + debugInfo }).Wait(); } else { lock (loggerLock) { currentTester = socketMessageLayer; } var currenTestPair = new TestPair { TesterSocket = socketMessageLayer, GameName = request.GameAssembly, Process = process }; processes[request.GameAssembly] = currenTestPair; testerToGame[socketMessageLayer] = currenTestPair; socketMessageLayer.Send(new LogRequest { Message = "Process created, id: " + process.Id.ToString() }).Wait(); } break; } } } else //Game process { TestPair pair; if (!processes.TryGetValue(request.GameAssembly, out pair)) { return; } pair.GameSocket = socketMessageLayer; testerToGame[pair.TesterSocket] = pair; gameToTester[pair.GameSocket] = pair; pair.TesterSocket.Send(new StatusMessageRequest { Error = false, Message = "Start" }).Wait(); Console.WriteLine($"Starting test {request.GameAssembly}"); } }); socketMessageLayer.AddPacketHandler <KeySimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler <TapSimulationRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler <ScreenshotRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); }); socketMessageLayer.AddPacketHandler <TestEndedRequest>(request => { var game = testerToGame[socketMessageLayer]; game.GameSocket.Send(request).Wait(); testerToGame.Remove(socketMessageLayer); gameToTester.Remove(game.GameSocket); processes.Remove(game.GameName); socketMessageLayer.Context.Dispose(); game.GameSocket.Context.Dispose(); game.Process.Kill(); game.Process.Dispose(); lock (loggerLock) { currentTester = null; } Console.WriteLine($"Finished test {game.GameName}"); }); socketMessageLayer.AddPacketHandler <TestAbortedRequest>(request => { var game = testerToGame[socketMessageLayer]; testerToGame.Remove(socketMessageLayer); processes.Remove(game.GameName); socketMessageLayer.Context.Dispose(); game.Process.Kill(); game.Process.Dispose(); lock (loggerLock) { currentTester = null; } Console.WriteLine($"Aborted test {game.GameName}"); }); socketMessageLayer.AddPacketHandler <ScreenShotPayload>(request => { var tester = gameToTester[socketMessageLayer]; var imageData = new TestResultImage(); var stream = new MemoryStream(request.Data); imageData.Read(new BinaryReader(stream)); stream.Dispose(); var resultFileStream = File.OpenWrite(request.FileName); imageData.Image.Save(resultFileStream, ImageFileType.Png); resultFileStream.Dispose(); tester.TesterSocket.Send(new ScreenshotStored()).Wait(); }); Task.Run(async() => { try { await socketMessageLayer.MessageLoop(); } catch { } }); }
/// <summary> /// Receiving constructor /// </summary> /// <param name="state"></param> /// <param name="socket"></param> /// <param name="debug"></param> internal SimpleMessage(ClientMetadata state, SimpleSocket socket, bool debug = false) { _debug = debug; _state = state; _socket = socket; }
private SimpleSocket CreateSocketContext(bool task) { var socketContext = new SimpleSocket(); socketContext.Connected = (clientSocketContext) => { Task.Run(async() => { try { // Register service server await socketContext.WriteStream.WriteInt16Async(task ? (short)RouterMessage.TaskProvideServer : (short)RouterMessage.ServiceProvideServer); await socketContext.WriteStream.WriteStringAsync(serverUrl); await socketContext.WriteStream.FlushAsync(); while (true) { var routerMessage = (RouterMessage)await socketContext.ReadStream.ReadInt16Async(); switch (routerMessage) { case RouterMessage.ServiceRequestServer: { var requestedUrl = await clientSocketContext.ReadStream.ReadStringAsync(); var guid = await clientSocketContext.ReadStream.ReadGuidAsync(); // Spawn actual server var realServerSocketContext = new SimpleSocket(); realServerSocketContext.Connected = async(clientSocketContext2) => { // Write connection string await clientSocketContext2.WriteStream.WriteInt16Async((short)RouterMessage.ServerStarted); await clientSocketContext2.WriteStream.WriteGuidAsync(guid); // Delegate next steps to actual server HandleClient(clientSocketContext2, requestedUrl); }; // Start connection await realServerSocketContext.StartClient(address, port); break; } default: Console.WriteLine("Router: Unknown message: {0}", routerMessage); throw new ArgumentOutOfRangeException(); } } } catch (Exception e) { // TODO: Ideally, separate socket-related error messages (disconnection) from real errors // Unfortunately, it seems we can't filter with SocketException/IOException only? Log.Info($"Client {clientSocketContext.RemoteAddress}:{clientSocketContext.RemotePort} disconnected with exception.", e); clientSocketContext.Dispose(); } }); }; return(socketContext); }
/// <summary> /// Handles ClientRequestServer messages. /// It will try to find a matching service (spawn it if not started yet), and ask it to establish a new "server" connection back to us. /// </summary> /// <param name="clientSocket">The client socket context.</param> /// <returns></returns> private async Task HandleMessageClientRequestServer(SimpleSocket clientSocket) { // Check for an existing server // TODO: Proper Url parsing (query string) var url = await clientSocket.ReadStream.ReadStringAsync(); string[] urlSegments; string urlParameters; RouterHelper.ParseUrl(url, out urlSegments, out urlParameters); if (urlSegments.Length == 0) { throw new InvalidOperationException("No URL Segments"); } SimpleSocket serverSocket = null; ExceptionDispatchInfo serverSocketCapturedException = null; try { // For now, we handle only "service" URL switch (urlSegments[0]) { case "service": { // From the URL, start service (if not started yet) and ask it to provide a server serverSocket = await SpawnServerFromService(url, false); break; } case "task": // From the URL, start service (if not started yet) and ask it to provide a server serverSocket = await SpawnServerFromService(url, true); break; default: throw new InvalidOperationException("This type of URL is not supported"); } } catch (Exception e) { serverSocketCapturedException = ExceptionDispatchInfo.Capture(e); } if (serverSocketCapturedException != null) { try { // Notify client that there was an error await clientSocket.WriteStream.WriteInt16Async((short)RouterMessage.ClientServerStarted); await clientSocket.WriteStream.WriteInt32Async(1); // error code Failure await clientSocket.WriteStream.WriteStringAsync(serverSocketCapturedException.SourceException.Message); await clientSocket.WriteStream.FlushAsync(); } finally { serverSocketCapturedException.Throw(); } } try { // Notify client that we've found a server for it await clientSocket.WriteStream.WriteInt16Async((short)RouterMessage.ClientServerStarted); await clientSocket.WriteStream.WriteInt32Async(0); // error code OK await clientSocket.WriteStream.FlushAsync(); // Let's forward clientSocketContext and serverSocketContext await await Task.WhenAny( ForwardSocket(clientSocket, serverSocket), ForwardSocket(serverSocket, clientSocket)); } catch { serverSocket.Dispose(); throw; } }
public void RaiseOnMessageReceived(SimpleSocket socket, IClientInfo client, object message, string header) { OnMessageReceived?.Invoke(socket, client, message, header); }
/// <summary> /// Handles ClientRequestServer messages. /// It will try to find a matching service (spawn it if not started yet), and ask it to establish a new "server" connection back to us. /// </summary> /// <param name="clientSocket">The client socket context.</param> /// <returns></returns> private async Task HandleMessageClientRequestServer(SimpleSocket clientSocket) { // Check for an existing server // TODO: Proper Url parsing (query string) var url = await clientSocket.ReadStream.ReadStringAsync(); Log.Info($"Client {clientSocket.RemoteAddress}:{clientSocket.RemotePort} sent message ClientRequestServer with URL {url}"); string[] urlSegments; string urlParameters; RouterHelper.ParseUrl(url, out urlSegments, out urlParameters); if (urlSegments.Length == 0) { throw new InvalidOperationException("No URL Segments"); } SimpleSocket serverSocket = null; ExceptionDispatchInfo serverSocketCapturedException = null; try { // For now, we handle only "service" URL switch (urlSegments[0]) { case "service": { // From the URL, start service (if not started yet) and ask it to provide a server serverSocket = await SpawnServerFromService(url, false); break; } case "task": { // From the URL, start service (if not started yet) and ask it to provide a server serverSocket = await SpawnServerFromService(url, true); } break; case "redirect": { // Redirect to a IP/port serverSocket = new SimpleSocket(); var host = urlSegments[1]; var port = int.Parse(urlSegments[2]); // Note: for security reasons, we currently use a whitelist //if (host == "xenkobuild.xenko.com" && port == 1832) // await serverSocket.StartClient(host, port, false); //else throw new InvalidOperationException("Trying to redirect to a non-whitelisted host/port"); break; } default: throw new InvalidOperationException("This type of URL is not supported"); } } catch (Exception e) { serverSocketCapturedException = ExceptionDispatchInfo.Capture(e); } if (serverSocketCapturedException != null) { try { // Notify client that there was an error await clientSocket.WriteStream.WriteInt16Async((short)RouterMessage.ClientServerStarted); await clientSocket.WriteStream.WriteInt32Async(1); // error code Failure await clientSocket.WriteStream.WriteStringAsync(serverSocketCapturedException.SourceException.Message); await clientSocket.WriteStream.FlushAsync(); } finally { serverSocketCapturedException.Throw(); } } try { // Notify client that we've found a server for it await clientSocket.WriteStream.WriteInt16Async((short)RouterMessage.ClientServerStarted); await clientSocket.WriteStream.WriteInt32Async(0); // error code OK await clientSocket.WriteStream.FlushAsync(); // Let's forward clientSocketContext and serverSocketContext await await Task.WhenAny( ForwardSocket(clientSocket, serverSocket), ForwardSocket(serverSocket, clientSocket)); } catch { serverSocket.Dispose(); throw; } }
/// <summary> /// Called when a new client connection has been established. /// Before writing anything to the stream, HandleClient is responsible for either calling <see cref="AcceptConnection"/> or <see cref="RefuseConnection"/>. /// </summary> /// <param name="clientSocket">The client socket.</param> /// <param name="url">The requested URL.</param> protected abstract void HandleClient(SimpleSocket clientSocket, string url);
private static void ConnectedToServer(SimpleSocket a) { WriteLine("The client has connected to the server on ip " + a.Ip); }
private static void ServerMessageReceived(SimpleSocket a, string msg) { WriteLine("Message received from the server: " + msg); }
private static void CustomHeader(SimpleSocket a, object msg, IDictionary <object, object> dict, Type objectType) { WriteLine("Test"); // WriteLine("Bytes received from server with header = " + header + " and message = " + msg); }
private static void ErrorThrown(SimpleSocket socketClient, Exception error) { WriteLine("The client has thrown an error: " + error.Message); WriteLine("Stacktrace: " + error.StackTrace); }
// Handles the MessageContractA private static void MessageAContractOnOnMessageReceived(SimpleSocket socket, IClientInfo clientInfo, object message, string header) { WriteLine("Server received a MessageContract from the client with id " + clientInfo.Id + " the header is : " + header + " and the message reads: " + message.ToString()); }
private static void CustomHeader(SimpleSocket a, string msg, string header) { WriteLine("Bytes received from server with header = " + header + " and message = " + msg); }
public async Task Run() { Services = new ServiceRegistry(); // Database file provider Services.AddService <IDatabaseFileProviderService>(new DatabaseFileProviderService(new DatabaseFileProvider(ObjectDatabase.CreateDefaultDatabase()))); // Content manager Content = new ContentManager(Services); Services.AddService <IContentManager>(Content); Services.AddService(Content); //Services.AddService<IGraphicsDeviceService>(new GraphicsDeviceServiceLocal(null)); // Game systems var gameSystems = new GameSystemCollection(Services); Services.AddService <IGameSystemCollection>(gameSystems); gameSystems.Initialize(); // Load scene (physics only) var loadSettings = new ContentManagerLoaderSettings { // Ignore all references (Model, etc...) ContentFilter = ContentManagerLoaderSettings.NewContentFilterByType() }; var scene = await Content.LoadAsync <Scene>("MainScene", loadSettings); var sceneInstance = new SceneInstance(Services, scene, ExecutionMode.None); var sceneSystem = new SceneSystem(Services) { SceneInstance = sceneInstance, }; Services.AddService(sceneSystem); var physics = new PhysicsProcessor(); sceneInstance.Processors.Add(physics); var socket = new SimpleSocket(); socket.Connected += clientSocket => { Console.WriteLine("Client connected"); var reader = new BinarySerializationReader(clientSocket.ReadStream); while (true) { // Receive ray start/end var start = reader.Read <Vector3>(); var end = reader.Read <Vector3>(); // Raycast var result = physics.Simulation.Raycast(start, end); Console.WriteLine($"Performing raycast: {(result.Succeeded ? "hit" : "miss")}"); // Send result clientSocket.WriteStream.WriteByte((byte)(result.Succeeded ? 1 : 0)); clientSocket.WriteStream.Flush(); } }; await socket.StartServer(2655, false); Console.WriteLine("Server listening, press a key to exit"); Console.ReadKey(); }
protected override async void HandleClient(SimpleSocket clientSocket, string url) { clientResultsEvent.Set(); await AcceptConnection(clientSocket); try { var binaryReader = new BinaryReader(clientSocket.ReadStream); //Read events TestRunnerMessageType messageType; do { messageType = (TestRunnerMessageType)binaryReader.ReadInt32(); switch (messageType) { case TestRunnerMessageType.TestStarted: { var testFullName = binaryReader.ReadString(); Console.WriteLine($"Test Started: {testFullName}"); clientResultsEvent.Set(); break; } case TestRunnerMessageType.TestFinished: { var testFullName = binaryReader.ReadString(); var status = binaryReader.ReadString(); Console.WriteLine($"Test {status}: {testFullName}"); clientResultsEvent.Set(); break; } case TestRunnerMessageType.TestOutput: { var outputType = binaryReader.ReadString(); var outputText = binaryReader.ReadString(); Console.WriteLine($" {outputType}: {outputText}"); clientResultsEvent.Set(); break; } case TestRunnerMessageType.SessionSuccess: testFailed = false; break; case TestRunnerMessageType.SessionFailure: testFailed = true; break; default: throw new ArgumentOutOfRangeException(); } } while (messageType != TestRunnerMessageType.SessionFailure && messageType != TestRunnerMessageType.SessionSuccess); // Mark test session as finished testFinished = true; //Read output var output = binaryReader.ReadString(); Console.WriteLine(output); // Read XML result var result = binaryReader.ReadString(); Console.WriteLine(result); // Write XML result to disk File.WriteAllText(resultFile, result); clientResultsEvent.Set(); } catch (Exception) { clientResultsEvent.Set(); Console.WriteLine(@"Client disconnected before sending results, a fatal crash might have occurred."); } }
private static void Disconnected(SimpleSocket a) { WriteLine("The client has disconnected from the server with ip " + a.Ip + "on port " + a.Port); }
private void RunTests() { AppDomain.CurrentDomain.UnhandledException += (a, e) => { var exception = e.ExceptionObject as Exception; if (exception != null) { var exceptionText = exception.ToString(); stringBuilder.Append($"Tests fatal failure: {exceptionText}"); Logger.Debug($"Unhandled fatal exception: {exception.ToString()}"); EndTesting(true); } }; var strideVersion = Intent.GetStringExtra(TestRunner.StrideVersion); var buildNumber = Parse(Intent.GetStringExtra(TestRunner.StrideBuildNumber) ?? "-1"); var branchName = Intent.GetStringExtra(TestRunner.StrideBranchName) ?? ""; // Remove extra (if activity is recreated) Intent.RemoveExtra(TestRunner.StrideVersion); Intent.RemoveExtra(TestRunner.StrideBuildNumber); Intent.RemoveExtra(TestRunner.StrideBranchName); Logger.Info(@"*******************************************************************************************************************************"); Logger.Info(@"date: " + DateTime.Now); Logger.Info(@"*******************************************************************************************************************************"); // Connect to server right away to let it know we're alive //var client = Connect(serverAddresses, serverPort); var url = "/task/Stride.TestRunner.exe"; socketContext = RouterClient.RequestServer(url).Result; socketBinaryWriter = new BinaryWriter(socketContext.WriteStream); // Update build number (if available) ImageTester.ImageTestResultConnection.BuildNumber = buildNumber; ImageTester.ImageTestResultConnection.BranchName = branchName ?? ""; ConnectToImageServer(); // Start unit test var cachePath = CacheDir.AbsolutePath; var timeNow = DateTime.Now; // Generate result file name resultFile = Path.Combine(cachePath, $"TestResult-{timeNow:yyyy-MM-dd_hh-mm-ss-tt}.xml"); Logger.Debug(@"Execute tests"); stringBuilder = new StringBuilder(); var stringWriter = new StringWriter(stringBuilder); try { new TextUI(stringWriter) { TestListener = this }.Execute(new[] { "-format:nunit2", $"-result:{resultFile}" }); } catch (Exception ex) { stringBuilder.Append($"Tests fatal failure: {ex}"); Logger.Error($"Tests fatal failure: {ex}"); } EndTesting(false); }
private static void ClientMessageSubmitted(SimpleSocket a, bool close) { WriteLine("The client has submitted a message to the server."); }
/// <summary> /// Initializes a new Shell core /// </summary> /// <param name="Socket">Socket to use</param> public ShellCore(SimpleSocket Socket) { this.TelnetServer = new TelnetServer(Socket); this.Prompt = ">"; }
private static void MessageFailed(SimpleSocket tcpClient, byte[] messageData, Exception exception) { WriteLine("The client has failed to send a message."); WriteLine("Error: " + exception); }
/// <summary> /// Let router knows that we want to continue with that connection. /// </summary> /// <param name="clientSocket">The client socket.</param> /// <returns></returns> protected async Task AcceptConnection(SimpleSocket clientSocket) { await clientSocket.WriteStream.WriteInt32Async(0); // error code OK await clientSocket.WriteStream.FlushAsync(); }
//Event for MessageContract (MessageA) //The clientId is only used on the server side. Here it will return -1 private static void MessageAContractOnOnMessageReceived(SimpleSocket client, IClientInfo clientInfo, object message, string header) { WriteLine("MessageContract received with header: " + header + " and with message " + message.ToString()); }
public Service(SimpleSocket socket) { Socket = socket; }
/// <inheritdoc/> protected override async void HandleClient(SimpleSocket clientSocket, string url) { string[] urlSegments; string urlParameters; RouterHelper.ParseUrl(url, out urlSegments, out urlParameters); var parameters = RouterHelper.ParseQueryString(urlParameters); var mode = parameters["mode"]; // We accept everything await AcceptConnection(clientSocket); var socketMessageLayer = new SocketMessageLayer(clientSocket, true); Guid?packageId = null; { Guid packageIdParsed; if (Guid.TryParse(parameters["packageid"], out packageIdParsed)) { packageId = packageIdParsed; } } if (mode == "gamestudio") { Console.WriteLine("GameStudio mode started!"); if (!packageId.HasValue) { return; } lock (gameStudioPerPackageId) { gameStudioPerPackageId[packageId.Value] = socketMessageLayer; } } else { // Create an effect compiler per connection var effectCompiler = new EffectCompiler(); Console.WriteLine("Client connected"); // TODO: Properly close the file, and choose where to copy/move it? var recordedEffectCompile = new EffectLogStore(new MemoryStream()); // TODO: This should come from an "init" packet effectCompiler.SourceDirectories.Add(EffectCompilerBase.DefaultSourceShaderFolder); // Make a VFS that will access remotely the DatabaseFileProvider // TODO: Is that how we really want to do that in the future? var networkVFS = new NetworkVirtualFileProvider(socketMessageLayer, "/asset"); VirtualFileSystem.RegisterProvider(networkVFS); effectCompiler.FileProvider = networkVFS; socketMessageLayer.AddPacketHandler <RemoteEffectCompilerEffectRequest>((packet) => ShaderCompilerRequestHandler(socketMessageLayer, recordedEffectCompile, effectCompiler, packet)); socketMessageLayer.AddPacketHandler <RemoteEffectCompilerEffectRequested>((packet) => { if (!packageId.HasValue) { return; } SocketMessageLayer gameStudio; lock (gameStudioPerPackageId) { if (!gameStudioPerPackageId.TryGetValue(packageId.Value, out gameStudio)) { return; } } // Forward to game studio gameStudio.Send(packet); }); } Task.Run(() => socketMessageLayer.MessageLoop()); }
// Use this for initialization void Start() { socketMorphology = new SimpleSocket (); sCallbacks = new MorphologyCraterCallback (vShaderCrater); socketMorphology.ConnectToServer (sCallbacks); }
public static bool Connect(SimpleSocket simpleSocket) { ImageComparisonServer = simpleSocket.Socket; return(OpenConnection()); }