예제 #1
0
        /// <summary>
        /// Emuulates SAP Adapter Receive Endpoint
        /// </summary>
        public void Initialise()
        {
            //RfcDestinationManager.RegisterDestinationConfiguration(new MyClientConfig());//1
            RfcServerManager.RegisterServerConfiguration(new SAPIDocReceiveConfiguration());//2

            Type[] handlers = new Type[1] {
                typeof(SAPIDocReceiveHandler)
            };                                                                                 //3
            RfcServer server = RfcServerManager.GetServer("SQLCONDA_SERVER_CONFIG", handlers); //3

            server.RfcServerError            += OnRfcServerError;
            server.RfcServerApplicationError += OnRfcServerError;

            //register TID specific handler
            server.TransactionIDHandler = new SAPTIDHandler();

            //server.TransactionIDHandler = new MyServerHandler();
            server.Start();//4

            Console.WriteLine("Server has been started. Press X to exit.\n");

            while (true)
            {
                if (Console.ReadLine().Equals("X"))
                {
                    break;
                }
            }
            server.Shutdown(true); //Shuts down
        }
예제 #2
0
        //
        // This example demonstrates how to implement a UnitID handler and dispatch bgRFC calls.
        //
        // The following coding on the ABAP side will submit a request for execution of STFC_CONNECTION in a background unit of type "T".
        // Sending background units of type "Q" requires a bit more work. See the ABAP programming manuals for that.
        // (Set up a destination NCO_SERVER - or whichever name you choose - as described above.)
        //
        // DATA: l_dest TYPE REF TO if_bgrfc_destination_outbound,
        //       l_unit TYPE REF TO if_trfc_unit_outbound.
        //
        // TRY.
        //   l_dest = cl_bgrfc_destination_outbound=>create( 'NCO_SERVER' ).
        // CATCH cx_bgrfc_invalid_destination.
        //   MESSAGE e103(bgrfc) WITH 'NCO_SERVER'.
        // ENDTRY.
        //
        // l_unit = l_dest->create_trfc_unit( ).
        //
        // CALL FUNCTION 'STFC_CONNECTION' IN BACKGROUND UNIT l_unit
        //   EXPORTING
        //     requtext = 'This time a bgRFC Call'.
        //
        // COMMIT WORK.
        //
        public static void ExampleBgRfcServer()
        {
            // Creates a server instance using the NCO_SERVER configuration and the function handler for STFC_CONNECTION
            RfcServer server = RfcServerManager.GetServer(NCO_SERVER_CONFIG_NAME, new Type[] { typeof(StfcConnectionStaticImpl) });

            // Register event handlers for internal and application errors
            server.RfcServerError            += OnRfcServerError;
            server.RfcServerApplicationError += OnRfcServerApplicationError;
            // Register unit ID handler
            if (server.UnitIDHandler == null)
            {
                server.UnitIDHandler = new MyUnitIDHandler();
            }
            // Start the server instance, i.e. open the connection(s) as defined by parameter REG_COUNT (RfcConfigParameters.RegCount)
            server.Start();
            Console.WriteLine();
            Console.WriteLine("Server started: {0}", server.Parameters.ToString());
            Console.WriteLine("You can now send requests for STFC_CONNECTION (synchronous or in background task) -- press X to stop the server");
            while (Console.ReadLine() != "X")
            {
                ;
            }
            Console.WriteLine("Server shutting down...");
            // Shut down the server, aborting any active calls
            server.Shutdown(true);
            // Remove error and TID handlers so that other examples using the same server can start from scratch
            server.RfcServerError            -= OnRfcServerError;
            server.RfcServerApplicationError -= OnRfcServerApplicationError;
            server.UnitIDHandler              = null;
        }
예제 #3
0
        public void OnRfcServerError(Object server, RfcServerErrorEventArgs errorEventData)
        {
            RfcServer rfcServer = server as RfcServer;
            RfcServerApplicationException appEx = errorEventData.Error as RfcServerApplicationException;

            if (appEx != null)
            {
                Console.WriteLine("RfcServerApplicationError occured in RFC server {0} :", rfcServer.Name);
            }
            else
            {
                Console.WriteLine("RfcServerError occured in RFC server {0} :", rfcServer.Name);
            }


            if (errorEventData.ServerContextInfo != null)
            {
                Console.WriteLine("RFC Caller System ID: {0} ", errorEventData.ServerContextInfo.SystemAttributes.SystemID);
                Console.WriteLine("RFC function Name: {0} ", errorEventData.ServerContextInfo.FunctionName);
            }

            Console.WriteLine("Error type: {0}", errorEventData.Error.GetType().Name);
            Console.WriteLine("Error message: {0}", errorEventData.Error.Message);

            if (appEx != null)
            {
                Console.WriteLine("Inner exception type: {0}", appEx.InnerException.GetType().Name);
                Console.WriteLine("Inner exception message: {0}", appEx.InnerException.Message);
            }
        }
예제 #4
0
        private static RfcConfiguration ConfigureByRfcConnectionString(RfcConfiguration rfcConfiguration, string defaultAlias, string connectionString)
        {
            rfcConfiguration.DefaultServer = defaultAlias;
            rfcConfiguration.RfcServers ??= new List <RfcServer>();
            rfcConfiguration.RfcServers.Clear();


            if (string.IsNullOrWhiteSpace(defaultAlias))
            {
                throw new RfcException("Required value is not entered in server settings: 'Alias'");
            }

            var rfcServerConnection = new RfcServer {
                Alias = defaultAlias
            };

            if (string.IsNullOrWhiteSpace(connectionString))
            {
                throw new RfcException("'ConnectionString' is required, please check your 'ConnectionString' information and try again.");
            }

            rfcServerConnection.ConnectionOptions.Parse(connectionString);
            rfcConfiguration.RfcServers.Add(rfcServerConnection);

            if (rfcConfiguration.RfcServers.Count > 1 && !rfcConfiguration.RfcServers.Exists(s => s.Alias == rfcConfiguration.DefaultServer))
            {
                throw new RfcException("The default server value is not included in the server definitions.");
            }

            return(rfcConfiguration);
        }
예제 #5
0
        //
        // This method is used as the event handler for internal server errors. Internal server errors are errors
        // that are not caused by the application, but are incurred by NCO3. Such errors include, but are not limited to,
        // communication errors (e.g., loss of connections), out of memory, etc.
        //
        private static void OnRfcServerError(Object server, RfcServerErrorEventArgs errorEventData)
        {
            RfcServer rfcServer = server as RfcServer;

            Console.WriteLine();
            Console.WriteLine(">>>>> RfcServerError occurred in RFC server {0}:", rfcServer.Name);
            ShowErrorEventData(errorEventData);
        }
예제 #6
0
        public virtual void Connect(string sapServerAlias)
        {
            if (!_rfcConfiguration.RfcServers.Exists(s => s.Alias == sapServerAlias))
            {
                throw new RfcException($"SAP server connection settings not found: '{sapServerAlias}'.");
            }

            RfcServer sapServer = _rfcConfiguration.RfcServers.Single(s => s.Alias == sapServerAlias);

            RfcConnectionParameter[] interopParameters = sapServer.ConnectionOptions.ToInterop();

            _rfcConnectionHandle = _interop.OpenConnection(interopParameters, (uint)interopParameters.Length, out RfcErrorInfo errorInfo);
            errorInfo.ThrowOnError(Clear);
        }
예제 #7
0
        private static RfcConfiguration ConfigureByRfcConnection(RfcConfiguration rfcConfiguration, string defaultConnectionAlias, IEnumerable <RfcServer> rfcConnections)
        {
            rfcConfiguration.DefaultServer = defaultConnectionAlias;
            rfcConfiguration.RfcServers ??= new List <RfcServer>();
            rfcConfiguration.RfcServers.Clear();

            foreach (var rfcConnection in rfcConnections)
            {
                if (rfcConfiguration.RfcServers.Any(s => s.Alias == rfcConnection.Alias))
                {
                    throw new RfcException("Multiple servers have the same 'Alias' value.");
                }

                if (string.IsNullOrWhiteSpace(rfcConnection.Alias))
                {
                    throw new RfcException("Required value is not entered in server settings: 'Alias'");
                }

                var rfcServerConnection = new RfcServer {
                    Alias = rfcConnection.Alias
                };

                if (rfcConnection.ConnectionPooling != null)
                {
                    rfcServerConnection.ConnectionPooling = rfcConnection.ConnectionPooling;
                }

                if (!string.IsNullOrWhiteSpace(rfcConnection.ConnectionString))
                {
                    rfcServerConnection.ConnectionOptions.Parse(rfcConnection.ConnectionString);
                }

                if (rfcConnection.ConnectionOptions != null)
                {
                    rfcServerConnection.ConnectionOptions = rfcConnection.ConnectionOptions;
                }

                rfcConfiguration.RfcServers.Add(rfcServerConnection);
            }

            if (rfcConfiguration.RfcServers.Count > 1 && !rfcConfiguration.RfcServers.Exists(s => s.Alias == rfcConfiguration.DefaultServer))
            {
                throw new RfcException("The default server value is not included in the server definitions.");
            }

            return(rfcConfiguration);
        }
예제 #8
0
        //
        // This example demonstrates a server permitting stateful requests.
        //
        // The easiest way to implement stateful scenarios is by using instance methods. In that case the .Net Connector runtime
        // will create a new instance of the handler class for each ABAP user session and keep the instance as long as the corresponding
        // stateful session is alive. This is the approach the current example will follow.
        // However, if creation/destruction of your classes implementing the "server functions" would be to expensive, you can as well
        // use static methods (avoiding object creation by the NCo runtime) and implement the necessary stateful behavior yourself
        // using RfcServerContext.SessionID inside the static server function implementation.
        //
        public static void ExampleStatefulServer()
        {
            // Creates a server instance using the NCO_SERVER configuration and the given function handler.
            // Stateful requests can be handled by instance methods only;
            // several handlers can be passed to the server - in this case there is only one.
            RfcServer server = RfcServerManager.GetServer(NCO_SERVER_CONFIG_NAME, new Type[] { typeof(StfcConnectionImpl) });

            // Start the server instance, i.e. open the connection(s) as defined by parameter REG_COUNT (RfcConfigParameters.RegCount)
            server.Start();
            Console.WriteLine();
            Console.WriteLine("Server started: {0}", server.Parameters.ToString());
            Console.WriteLine("You can now send (three) stateful requests (through STFC_CONNECTION only) -- press ENTER to stop the server");
            Console.ReadLine();
            Console.WriteLine("Server shutting down...");
            // Shut down the server, aborting any active calls
            server.Shutdown(true);
        }
예제 #9
0
        //
        // This method is used as the event handler for application errors raised while a server processes a requested function.
        // As opposed to internal errors these errors occur in application coding outside NCO3. Note that the application can throw
        // whichever type of exception it sees fit. It will be wrapped in a RfcServerApplicationException and made available as its
        // inner exception.
        //
        private static void OnRfcServerApplicationError(Object server, RfcServerErrorEventArgs errorEventData)
        {
            RfcServer rfcServer = server as RfcServer;

            Console.WriteLine();
            Console.WriteLine(">>>>> RfcServerApplicationError occurred in RFC server {0}:", rfcServer.Name);
            ShowErrorEventData(errorEventData);
            RfcServerApplicationException appEx = errorEventData.Error as RfcServerApplicationException;

            if (appEx != null)
            {
                Console.WriteLine("Inner exception type: {0}", appEx.InnerException.GetType().Name);
                Console.WriteLine("Inner exception message: {0}", appEx.InnerException.Message);
            }
            else
            {
                Console.WriteLine("WARNING: errorEventData.Error is not an instance of RfcServerApplicationError");
            }
        }
예제 #10
0
        private IRfcConnection GetConnection()
        {
            if (string.IsNullOrWhiteSpace(_activeServer))
            {
                if (string.IsNullOrWhiteSpace(_rfcConfiguration.DefaultServer))
                {
                    if (_rfcConfiguration.RfcServers.Count == 1)
                    {
                        _activeServer = _rfcConfiguration.RfcServers.Single().Alias;
                    }
                    else
                    {
                        throw new RfcException("The default SAP server could not be detected.");
                    }
                }
                else
                {
                    if (_rfcConfiguration.RfcServers.Exists(s => s.Alias == _rfcConfiguration.DefaultServer))
                    {
                        _activeServer = _rfcConfiguration.DefaultServer;
                    }
                    else
                    {
                        throw new RfcException("Default SAP server connection settings were not found.");
                    }
                }
            }

            RfcServer server = _rfcConfiguration.RfcServers.Single(s => s.Alias == _activeServer);

            if (server.ConnectionPooling.Enabled)
            {
                IRfcConnectionPoolServiceFactory factory = _serviceProvider.GetRequiredService <IRfcConnectionPoolServiceFactory>();
                IRfcConnectionPool connectionPool        = factory.GetService(_activeServer);

                return(connectionPool.GetConnection());
            }

            IRfcConnection rfcConnection = _serviceProvider.GetRequiredService <IRfcConnection>();

            rfcConnection.Connect(_activeServer);
            return(rfcConnection);
        }
예제 #11
0
        //
        // This example demonstrates a minimal server implementation using a static function handler.
        //
        // Once the server is started STFC_CONNECTION can be called on the ABAP side using
        // the above mentioned SM59 destination. Any other function module will incur an error
        // (a SYSTEM_FAILURE) since only STFC_CONNECTION can be handled by the handler
        // supplied to the server.
        //
        public static void ExampleSimpleServer()
        {
            // Creates a server instance using the NCO_SERVER configuration and the given array of function handlers.
            // Static function handlers are suited for stateless functions;
            // several handlers can be passed to the server - in this case there is only one.
            RfcServer server = RfcServerManager.GetServer(NCO_SERVER_CONFIG_NAME, new Type[] { typeof(StfcConnectionStaticImpl) });

            // You may, or may not, want the default trace level to match the trace level of the server -- comment or uncomment the following line
            //RfcTrace.DefaultTraceLevel = server.Parameters.GetTraceLevelAsUint();
            // Start the server instance, i.e. open the connection(s) as defined by parameter REG_COUNT (RfcConfigParameters.RegCount)
            server.Start();
            Console.WriteLine();
            Console.WriteLine("Server started: {0}", server.Parameters.ToString());
            Console.WriteLine("You can now send requests (through STFC_CONNECTION only) -- press ENTER to stop the server");
            Console.ReadLine();
            Console.WriteLine("Server shutting down...");
            // Shut down the server, aborting any active calls
            server.Shutdown(true);
        }
예제 #12
0
        //
        // This example demonstrates how to return the different error types to ABAP.
        // These are described in more detail in the class RaiseErrorImpl, see comments there for more information.
        // In order to call this server, use an ABAP report like the one in Z_CALL_EXTERNAL_SERVER.abap available in this tutorial.
        //
        //
        public static void ExampleThrowErrors()
        {
            // Creates a server instance using the NCO_SERVER configuration and the function handler for RFC_RAISE_ERROR
            RfcServer server = RfcServerManager.GetServer(NCO_SERVER_CONFIG_NAME, new Type[] { typeof(RaiseErrorImpl) });

            // Register event handlers for internal and application errors
            server.RfcServerError            += OnRfcServerError;
            server.RfcServerApplicationError += OnRfcServerApplicationError;
            // Start the server instance, i.e. open the connection(s) as defined by parameter REG_COUNT (RfcConfigParameters.RegCount)
            server.Start();
            Console.WriteLine();
            Console.WriteLine("Server started: {0}", server.Parameters.ToString());
            Console.WriteLine("You can now send requests (using ABAP report Z_CALL_EXTERNAL_SERVER) -- press ENTER to stop the server");
            Console.ReadLine();
            Console.WriteLine("Server shutting down...");
            // Shut down the server, aborting any active calls
            server.Shutdown(true);
            // Remove error handlers so that other examples using the same server can start from scratch
            server.RfcServerError            -= OnRfcServerError;
            server.RfcServerApplicationError -= OnRfcServerApplicationError;
        }
예제 #13
0
        //
        // This example demonstrates how to implement a generic function handler.
        //
        // In a generic function handler the handling method (or several such methods) is not limited
        // to a particular function through the annotation. Instead, the annotation designates the method
        // as a default handler which takes on any request that is not handled otherwise.
        //
        // In the example the static handler for STFC_CONNECTION is passed to the server together with
        // a generic handler. Thus STFC_CONNECTION will be handled by the handler specializing on that
        // very function, whereas the generic handler takes care of everything else.
        //
        // In this example handlers for server and application errors are registered that produce console
        // output in case such errors occur. As the preceding examples showed, registering event handlers
        // of this kind is not necessary. It is, however, a way to be notified and to take appropriate
        // actions, should issues arise.
        //
        // Note that the generic handler in this example does not really handle any (other) function
        // sensibly. It simply does nothing, which may in effect result in a successful call in many cases.
        //
        public static void ExampleGenericServer()
        {
            // Creates a server instance using the NCO_SERVER configuration and the function handler for STFC_CONNECTION and a generic handler
            RfcServer server = RfcServerManager.GetServer(NCO_SERVER_CONFIG_NAME, new Type[] { typeof(ServerFunctionGenericImpl), typeof(StfcConnectionStaticImpl) });

            // Register event handlers for internal and application errors
            server.RfcServerError            += OnRfcServerError;
            server.RfcServerApplicationError += OnRfcServerApplicationError;
            // Start the server instance, i.e. open the connection(s) as defined by parameter REG_COUNT (RfcConfigParameters.RegCount)
            server.Start();
            Console.WriteLine();
            Console.WriteLine("Server started: {0}", server.Parameters.ToString());
            Console.WriteLine("You can now send requests (through any function module) -- press ENTER to stop the server");
            Console.ReadLine();
            Console.WriteLine("Server shutting down...");
            // Shut down the server, aborting any active calls
            server.Shutdown(true);
            // Remove error handlers so that other examples using the same server can start from scratch
            server.RfcServerError            -= OnRfcServerError;
            server.RfcServerApplicationError -= OnRfcServerApplicationError;
        }
예제 #14
0
        private static RfcConfiguration ConfigureByConfiguration(RfcConfiguration rfcConfiguration, IConfiguration configuration, string section)
        {
            IConfigurationSection configurationSection = configuration.GetSection(section);

            if (configurationSection == null || !configurationSection.Exists())
            {
                return(rfcConfiguration);
            }

            rfcConfiguration.DefaultServer = configurationSection.GetValue <string>(DEFAULT_CONNECTION_KEY);
            rfcConfiguration.RfcServers ??= new List <RfcServer>();
            rfcConfiguration.RfcServers.Clear();

            IConfigurationSection connectionsSection = configurationSection.GetSection(RFC_SERVERS_KEY);

            if (connectionsSection == null || !connectionsSection.Exists())
            {
                return(rfcConfiguration);
            }

            foreach (IConfigurationSection rfcServerConnectionSection in connectionsSection.GetChildren())
            {
                string alias = rfcServerConnectionSection.GetValue <string>(ALIAS_KEY);
                if (rfcConfiguration.RfcServers.Any(s => s.Alias == alias))
                {
                    throw new RfcException("Application settings are not configured correctly. Multiple servers have the same 'Alias' value.");
                }

                if (string.IsNullOrWhiteSpace(alias))
                {
                    throw new RfcException("Application settings are not configured correctly. Required value is not entered in server settings: 'Alias'");
                }

                var rfcServerConnection = new RfcServer {
                    Alias = alias
                };

                IConfigurationSection poolingSection = rfcServerConnectionSection.GetSection(CONNECTION_POOLING_KEY);

                if (poolingSection != null && poolingSection.Exists())
                {
                    poolingSection.Bind(rfcServerConnection.ConnectionPooling);
                }

                rfcServerConnection.ConnectionString = rfcServerConnectionSection.GetValue <string>(CONNECTION_STRING_KEY);

                if (!string.IsNullOrWhiteSpace(rfcServerConnection.ConnectionString))
                {
                    rfcServerConnection.ConnectionOptions.Parse(rfcServerConnection.ConnectionString);
                }

                IConfigurationSection connectionOptionsSection = rfcServerConnectionSection.GetSection(CONNECTION_OPTIONS_KEY);

                if (connectionOptionsSection != null && connectionOptionsSection.Exists())
                {
                    connectionOptionsSection.Bind(rfcServerConnection.ConnectionOptions);
                }

                rfcConfiguration.RfcServers.Add(rfcServerConnection);
            }

            if (rfcConfiguration.RfcServers.Count > 1 && !rfcConfiguration.RfcServers.Exists(s => s.Alias == rfcConfiguration.DefaultServer))
            {
                throw new RfcException("Application settings are not configured correctly. The default server value is not included in the server definitions.");
            }

            return(rfcConfiguration);
        }
예제 #15
0
        /// <summary>
        /// Emulates SAP Adapter Receive Endpoint
        /// </summary>
        public void Initialise()
        {
            //hard coded for testing but will pick up from ProgId in config
            string serverName = "SQLARTMAS_SERVER";
            string progId     = "SQLARTMAS";

            SAPTIDHandler rfcTIDHandler = new SAPTIDHandler();

            try
            {
                if (_sapIDocReceiveConfiguration == null)
                {
                    _sapIDocReceiveConfiguration =
                        new SAPIDocReceiveConfiguration(serverName, _rfcDestination.Name, progId);
                }
                else
                {
                    _sapIDocReceiveConfiguration.AddParameters(serverName, progId);
                }

                RfcServerManager.RegisterServerConfiguration(_sapIDocReceiveConfiguration);

                Type[] handlers = new Type[1] {
                    typeof(SAPIDocReceiveHandler)
                };                                                          //3
                _server = RfcServerManager.GetServer(serverName, handlers); //3

                _server.RfcServerError            += OnRfcServerError;
                _server.RfcServerApplicationError += OnRfcServerError;

                SAPIDocReceiveHandler.IDocEndReceiveCompleteEvent +=
                    new SAPIDocReceiveHandler.IDocReceiveEventHandler(OnIDocEndReceiveComplete);

                SAPIDocReceiveHandler.IDocBeginReceiveCompleteEvent +=
                    new SAPIDocReceiveHandler.IDocReceiveEventHandler(OnIDocBeginReceiveComplete);

                // register for session startevent in order to capture SessionId
                rfcTIDHandler.IDocSessionStart += new SAPTIDHandler.IDocsSessionEventHandler(OnRfcSessionStart);

                //register TID specific handler
                _server.TransactionIDHandler = rfcTIDHandler;

                // Create a new session for this particular destination
                // RfcSessionManager.BeginContext(_rfcDestination);


                //server.TransactionIDHandler = new MyServerHandler();
                _server.Start();//4
            }

            catch (RfcInvalidStateException rfcEx)
            {
                // cascade up callstack
                throw rfcEx;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }
            //Type[] handlers = new Type[1] { typeof(SAPIDocReceiveHandler) };//3
            //RfcServer server = RfcServerManager.GetServer("SQLARTMAS", handlers);//3



            //Console.WriteLine("Server has been started. Press X to exit.\n");

            //while (true)
            //{
            //    if (Console.ReadLine().Equals("X")) break;
            //}
            //server.Shutdown(true); //Shuts down
        }
예제 #16
0
        public void OnRfcServerStateChanged(object server, RfcServerStateChangedEventArgs stateEventData)
        {
            RfcServer serverStatus = server as RfcServer;

            System.Diagnostics.Trace.WriteLine(serverStatus.Name);
        }
예제 #17
0
        /// <summary>
        /// http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/23051
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure(new FileInfo("log4net.config"));
            log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            log.Info("服务器启动,加载SAP配置!!");
            Console.WriteLine("服务器启动,加载SAP配置!!");
            try
            {
                SAPINT.SapConfig.SAPConfigFromFile.LoadSAPAllConfig();

                //1 Register the relevant destination object.
                //2 Get the destination corresponding to the ABAP system you want to call.
                //3 Next you need a repository for the metadata from the ABAP Dictionary of the corresponding destination system.
                //4 Create a function object (that will hold the values of the relevant parameters)
                //5 Provide the values for the relevant importing parameters of the function.
                //6 Execute the function.
                //7 Read the exporting or returning parameters and process them.


                // RfcDestinationManager.RegisterDestinationConfiguration(new MyBackendConfig());//1
                // RfcServerManager.RegisterServerConfiguration(new MyServerConfig());//2

                Type[] handlers = new Type[1] {
                    typeof(MiniServerHandler)
                };                                                          //3
                string defaultServer = ConfigFileTool.SAPGlobalSettings.GetDefultSAPServer();
                Console.WriteLine("Default server is : " + defaultServer);
                RfcServer server = RfcServerManager.GetServer(defaultServer, handlers);//3

                server.RfcServerError            += OnRfcServerError;
                server.RfcServerApplicationError += OnRfcServerApplicationError;

                if (server.TransactionIDHandler == null)
                {
                    server.TransactionIDHandler = new MyTidHandler();
                }

                server.Start();//4

                Console.WriteLine();
                Console.WriteLine("Server started: {0}", server.Parameters.ToString());
                Console.WriteLine("You can now send requests for STFC_CONNECTION (synchronous or in background task) -- press X to stop the server");
                while (true)
                {
                    if (Console.ReadLine().Equals("X"))
                    {
                        break;
                    }
                }
                server.Shutdown(true); //Shuts down
                server.RfcServerError            -= OnRfcServerError;
                server.RfcServerApplicationError -= OnRfcServerApplicationError;
                server.TransactionIDHandler       = null;
                //immediately aborting ongoing requests.
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error Occurs," + ex.Message);

                Console.ReadLine();
                //throw;
            }
        }