다음을 통해 공유


WCF 서비스 모델을 사용하여 SAP에서 인바운드 RFC 호출 수신

mySAP Business Suite용 Microsoft BizTalk 어댑터는 SAP 시스템에서 호출한 RFC를 수신하는 RFC 서버 역할을 할 수 있습니다.

WCF 서비스 모델에서 인바운드 RFC를 받으려면 다음을 수행해야 합니다.

  • SAP 시스템에 RFC 대상이 있는지 확인합니다.

  • RFC가 SAP 시스템에 정의되어 있는지 확인합니다.

  • 어댑터가 노출하는 메타데이터에서 RFC 작업에 대한 WCF 서비스 계약(인터페이스)을 생성합니다. 이렇게 하려면 어댑터 서비스 참조 Visual Studio 플러그 인 추가 또는 ServiceModel 메타데이터 유틸리티 도구(svcutil.exe)를 사용합니다.

  • 이 인터페이스에서 WCF 서비스를 구현합니다. WCF 서비스의 메서드에는 RFC를 처리하고 어댑터(따라서 SAP 시스템)에 대한 응답을 반환하는 데 필요한 논리가 포함되어 있습니다.

  • 서비스 호스트(System.ServiceModel.ServiceHost)를 사용하여 이 WCF 서비스를 호스트합니다.

    다음 섹션에서는 SAP 어댑터를 사용하여 SAP 시스템에서 RFC를 수신하는 방법을 보여줍니다.

SAP 어댑터에 RFC를 보내도록 SAP 시스템을 설정하는 방법

SAP 시스템에서 SAP 어댑터로 RFC를 보내려면 먼저 SAP 시스템에서 다음이 올바른지 확인해야 합니다.

  • SAP 어댑터의 RFC 대상이 있어야 합니다. SAP 어댑터는 SAP 시스템에서 RFC를 수신하기 위해 RFC 대상에 등록합니다. SAP 게이트웨이 호스트, SAP 게이트웨이 서비스 및 어댑터가 자신을 등록하는 데 사용하는 SAP 프로그램 ID와 같은 SAP 연결 URI에 매개 변수를 제공합니다. SAP에서 RFC 대상을 설정하는 방법에 대한 자세한 내용은 RFC, RFC 대상 만들기 및 SAP 시스템에서 RFC 보내기를 참조하세요.

  • RFC는 SAP 시스템에 정의되어야 합니다. SAP 시스템에서 RFC를 정의하는 함수 모듈을 만들어야 합니다. SAP 어댑터는 SAP 시스템의 RFC 정의를 사용하여 RFC에 대한 메타데이터를 검색합니다(디자인 타임과 런타임 모두). 자세한 내용은 SAP 시스템에서 RFC 만들기를 참조하세요.

    참고

    SAP 시스템에서 RFC를 정의해야 합니다. 그러나 어댑터 클라이언트 코드에서 RFC를 구현합니다. 어댑터가 RFC에 대한 메타데이터를 검색할 수 있도록 SAP 시스템에서 RFC를 정의해야 합니다.

    다음은 두 개의 정수 를 추가하고 결과를 반환하는 RFC에 대한 SAP 시스템의 소스 코드 예제입니다. 이 코드는 지정된 대상을 통해 RFC를 호출하기만 합니다. 함수의 구현은 SAP 어댑터 클라이언트 코드에 의해 수행됩니다.

FUNCTION Z_RFC_SAMPLE_ADD.  
*"---------------------------------------------------------------------*"*"Local interface:  
*"  IMPORTING  
*"     VALUE(X) TYPE  INT4  
*"     VALUE(Y) TYPE  INT4  
*"     VALUE(DEST) TYPE  CHAR20 DEFAULT 'SAPADAPTER'  
*"  EXPORTING  
*"     VALUE(RESULT) TYPE  INT4  
*"---------------------------------------------------------------------CALL FUNCTION 'Z_RFC_MKD_ADD' DESTINATION DEST  
  EXPORTING X = X  
            Y = Y  
  IMPORTING RESULT = RESULT.  
  
ENDFUNCTION.  

RFC에 대한 WCF 서비스 계약

어댑터 서비스 참조 Visual Studio 플러그 인 추가 또는 serviceModel 메타데이터 유틸리티 도구(svcutil.exe)를 사용하여 SAP 시스템에서 수신하려는 RFC에 대한 WCF 서비스 계약을 생성합니다. 다음 섹션에서는 Z_RFC_MKD_ADD 작업에 대해 생성된 관리 코드 클래스 및 인터페이스를 보여 줍니다.

Rfc 인터페이스(WCF 서비스 계약)

SAP 어댑터는 단일 서비스 계약인 "Rfc"에 따라 모든 RFC 작업을 표시합니다. 즉, 수신하려는 모든 RFC 작업에 대해 단일 인터페이스 Rfc가 만들어집니다. 각 대상 RFC 작업은 이 인터페이스의 메서드로 표시됩니다. 각 메서드는 작업의 요청 메시지에 대한 메시지 계약을 나타내는 단일 매개 변수를 사용하고 작업의 응답 메시지의 메시지 계약을 나타내는 개체를 반환합니다.

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/", ConfigurationName="Rfc")]  
public interface Rfc {  
  
    // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.Sap/2007/03/Rfc/) of message Z_RFC_MKD_ADDRequest does not match the default value (http://Microsoft.LobServices.Sap/2007/03/)  
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.LobServices.Sap/2007/03/Rfc/Z_RFC_MKD_ADD", ReplyAction="http://Microsoft.LobServices.Sap/2007/03/Rfc/Z_RFC_MKD_ADD/response")]  
    Z_RFC_MKD_ADDResponse Z_RFC_MKD_ADD(Z_RFC_MKD_ADDRequest request);  
}  
  

요청 및 응답 메시지

각 RFC 작업은 요청 메시지를 나타내는 매개 변수를 사용하고 응답 메시지를 나타내는 개체를 반환합니다. 요청 메시지의 속성에는 RFC의 IMPORT 및 (입력) CHANGE 매개 변수가 포함됩니다. 응답 메시지의 속성에는 작업에 대한 EXPORT 및 (출력) CHANGE 매개 변수가 포함됩니다.

[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.MessageContractAttribute(WrapperName="Z_RFC_MKD_ADD", WrapperNamespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", IsWrapped=true)]  
public partial class Z_RFC_MKD_ADDRequest {  
  
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", Order=0)]  
    public string DEST;  
  
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", Order=1)]  
    public System.Nullable<int> X;  
  
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", Order=2)]  
    public System.Nullable<int> Y;  
  
    public Z_RFC_MKD_ADDRequest() {  
    }  
  
    public Z_RFC_MKD_ADDRequest(string DEST, System.Nullable<int> X, System.Nullable<int> Y) {  
        this.DEST = DEST;  
        this.X = X;  
        this.Y = Y;  
    }  
}  
  
[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.MessageContractAttribute(WrapperName="Z_RFC_MKD_ADDResponse", WrapperNamespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", IsWrapped=true)]  
public partial class Z_RFC_MKD_ADDResponse {  
  
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.Sap/2007/03/Rfc/", Order=0)]  
    public int RESULT;  
  
    public Z_RFC_MKD_ADDResponse() {  
    }  
  
    public Z_RFC_MKD_ADDResponse(int RESULT) {  
        this.RESULT = RESULT;  
    }  
}  

생성된 WCF 서비스

어댑터 서비스 참조 플러그 인 추가는 WCF 서비스 계약(Rfc)을 구현하는 WCF 서비스도 생성합니다. 이 클래스의 메서드는 스텁됩니다. 이 클래스는 별도의 파일에서 생성됩니다. 이 클래스의 메서드에서 직접 코드를 구현할 수 있습니다.

namespace SAPBindingNamespace {  
  
    public class SAPBindingService : Rfc {  
  
        // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.Sap/2007/03/Rfc/) of message Z_RFC_MKD_ADDRequest does not match the default value (http://Microsoft.LobServices.Sap/2007/03/)  
        public virtual Z_RFC_MKD_ADDResponse Z_RFC_MKD_ADD(Z_RFC_MKD_ADDRequest request) {  
            throw new System.NotImplementedException("The method or operation is not implemented.");  
        }  
    }  
}  

RFC 서버 애플리케이션을 만드는 방법

WCF 서비스 모델을 사용하여 SAP 시스템에서 RFC를 받으려면 SAP 어댑터를 사용하여 WCF 서비스 모델 개요의 단계를 수행할 수 있습니다. 서비스 엔드포인트를 추가할 때 서비스 계약에 대해 'Rfc'를 지정해야 합니다(WCF 서비스를 만들고 구현하는 절차의 6단계).

다음 코드에서는 SAP 어댑터를 사용하여 SAP 시스템에서 Z_RFC_MKD_RFC 받는 방법에 대한 전체 예제를 보여 있습니다. 이 RFC는 두 개의 정수 매개 변수를 사용하고 결과를 SAP 시스템에 반환합니다.

using System;  
using System.Collections.Generic;  
using System.Text;  
  
// Add WCF, WCF LOB Adapter SDK, and SAP adapter namepaces  
using System.ServiceModel;  
using Microsoft.Adapters.SAP;  
using Microsoft.ServiceModel.Channels;  
  
// Include this namespace for the WCF LOB Adapter SDK and SAP adapter exceptions  
using Microsoft.ServiceModel.Channels.Common;  
  
namespace SapRfcServerSM  
{  
    // Implement a WCF service callback class by sub-classing the generated service callback class (SAPBindingService).  
    // You must annotate this class with the InstanceContextMode.Single ServiceBehavior  
    // If you implement your code in SAPBindingService.cs be sure to annotate the SAPBindingService class  
    // The callback method should return a Z_RFC_MKD_ADDResponse to indicate successful processing  
    // or throw an exception to indicate an error.  
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,UseSynchronizationContext = false)]  
    class RfcServerClass : SAPBindingNamespace.SAPBindingService  
    {  
  
        public override Z_RFC_MKD_ADDResponse Z_RFC_MKD_ADD(Z_RFC_MKD_ADDRequest request)  
        {  
            // If either parameter is null, throw an exception   
            if (request.X == null || request.Y == null)  
                throw new System.ArgumentNullException();  
  
            int result = (int) (request.X + request.Y);  
  
            Console.WriteLine("\nRfc Received");  
            Console.WriteLine("X =\t\t" + request.X.ToString());  
            Console.WriteLine("Y =\t\t" + request.Y.ToString());  
            Console.WriteLine("Result =\t" + result);  
            Console.WriteLine("\nHit <RETURN> to end");  
  
            return new Z_RFC_MKD_ADDResponse(result);  
        }  
  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            // Listener connection for the service URI -- the connection URI must contain credentials  
            Uri serviceUri = new Uri("sap://User=YourUserName;Passwd=YourPassword;Client=800;Lang=EN;@a/ADAPSAP47/00?ListenerGwServ=SAPGW00&ListenerGwHost=ADAPSAP47&ListenerProgramId=ADDER");  
  
            // The baseUri cannot contain userinfoparams or query_string parameters  
            Uri[] baseUri = new Uri[] { new Uri("sap://a/ADAPSAP47/00") };  
  
            Console.WriteLine("RFC server sample started");  
  
            // create service instance  
            RfcServerClass rfcServerInstance = new RfcServerClass();  
  
            try  
            {  
                Console.WriteLine("Initializing service host -- please wait");  
                // Create and initialize a service host  
                using (ServiceHost srvHost = new ServiceHost(rfcServerInstance, baseUri))  
                {  
  
                    // Add service endpoint   
                    // Specify AcceptCredentalsInUri=true for the binding  
                    // NOTE: The contract for the service endpoint is "Rfc".  
                    //       This is the generated WCF service callback interface (see SAPBindingInterface.cs).  
                    SAPBinding binding = new SAPBinding();  
                    binding.AcceptCredentialsInUri = true;  
                    srvHost.AddServiceEndpoint("Rfc", binding, serviceUri);  
                    srvHost.Open();  
  
                    Console.WriteLine("\nReady to receive Z_RFC_MKD_ADD RFC");  
                    Console.WriteLine("Hit <RETURN> to end");  
  
                    // Wait to receive request  
                    Console.ReadLine();  
                }  
            }  
            catch (ConnectionException cex)  
            {  
                Console.WriteLine("Exception occurred connecting to the SAP system");  
                Console.WriteLine(cex.InnerException.Message);  
            }  
            catch (TargetSystemException tex)  
            {  
                Console.WriteLine("Exception occurred on the SAP system");  
                Console.WriteLine(tex.InnerException.Message);  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine("Exception is: " + ex.Message);  
                if (ex.InnerException != null)  
                {  
                    Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);  
                }  
            }  
        }  
    }  
}  

참고 항목

WCF 서비스 모델을 사용하여 애플리케이션 개발
RFC 작업에 대한 메시지 스키마