PyRFC 支持服务器端编程。什么是服务器端编程?有哪些技术要求?可以参考我的另外一篇博客:SAP接口编程 之JCo3.0系列(06) 。本篇主要介绍 PyRFC 的技术实现。
要点
- 服务器端编程的主要作用是实现 ABAP 主动调用
- 服务器端编程需要首先在 ABAP 中定义函数,该函数可以是一个空函数。外部服务器 (本质是 nwrfc sdk 的封装)需要对该函数进行注册。如果 ABAP 函数有实现代码,其实也不会运行 ABAP 代码
- SAP 需要在 SM59 中定义 RFC destination,包括 网关 (Gateway host)、网关服务号(Gateway service number ) 以及 Program Id。其中 gateway host 和 gateway service number 通过事务码 SMGW 查看和设置。
SM59 设置
1)RFC destination 是设置的目标,call function 时指定的 destination 与此一致
2)Connection Type 需要为 TCP/IP
工具栏中有 Connection Test 按钮,可以测试连接是否成功。
因为现在 Python 服务器还没有启动,测试失败。界面如下:
PyRFC 设置
PyRFC 需要有server parameters 的设置以及 SAP logon 参数的设置。server parameters 包括刚才的 gateway host, service name 和 program id。PyRFC 支持将这些参数写在 sapnwrfc.ini 文件中。比如,在我的测试机器上,这些配置参数如下:
根据我的测试, REG_COUNT 参数不能少,否则 Python 服务器不能成功连接到 SAP。
函数处理器
对 ABAP 调用的函数,需要在 pyrfc 中定义相应的处理器,在这里实现相应的功能。比如,对 ABAP 中 STFC_CONNECTION 函数,定义如下的处理器:
def my_stfc_connection(request_context=None, REQUTEXT=""):
"""Server function my_stfc_connection with the signature of ABAP function module STFC_CONNECTION."""
print("stfc connection invoked")
print("request_context", request_context)
print(f"REQUTEXT: {REQUTEXT}")
return {
"ECHOTEXT": REQUTEXT,
"RESPTEXT": "消息发送自 Python 服务器"
}
Python 服务器
接下来,实现 Python 服务器,在 Python 服务器中,注册刚才编写的函数处理器。
from threading import Thread
from pyrfc import Server, set_ini_file_directory
import os
def launch_server():
"""Start server."""
dir_path = os.path.dirname(os.path.realpath(__file__))
set_ini_file_directory(dir_path)
server = Server(
{"dest": "gateway"},
{"dest": "D01"},
{"check_date": False, "check_time": False, "port": 8081, "server_log": False}
)
print(server.get_server_attributes())
# expose python function my_stfc_connection as ABAP function STFC_CONNECTION, to be called by ABAP system
server.add_function("STFC_CONNECTION", my_stfc_connection )
# start server
server.serve()
# get server attributes
print(server.get_server_attributes())
在这里,set_ini_file_directory 函数的作用,是根据前面代码设置的路径,在该路径下查找 sapnwrfc.ini 文件,并且用 ini 文件中的信息创建 Server:
参数根据 gateway 和 D01 从 sapnwrfc.ini 文件获取相关参数:
启动服务器
server_thread = Thread(target=launch_server)
server_thread.start()
input("Press Enter to stop server...\n") # WPS110
# stop server
server_thread.join()
print("Server stoped")
在 SAP 启动的情况下,运行该代码。并且测试 SM59 的连接,已经成功:
SMGW 查看连接的客户端 (菜单:Goto -> Logged on Clients) :
ABAP 测试 STFC_CONNECTION 函数
测试:
也可以写一段代码来测试:
report znwrfc_server_test.
data: requtext like sy-lisel,
resp_text like sy-lisel,
echo_text like sy-lisel.
data: rfcdest like rfcdes-rfcdest value 'NONE'.
data: rfc_mess(128).
requtext = '你好,我是来自ABAP的消息!'.
rfcdest = 'NWRFC_SERVER'. " corresponds to the destination name defined in SM59
write: 'Call function STFC_CONNECTION using ', rfcdest.
call function 'STFC_CONNECTION' destination rfcdest
exporting
requtext = requtext
importing
echotext = echo_text
resptext = resp_text.
if sy-subrc is initial.
write: / 'Call STFC_CONNECTION'.
write: / resp_text.
endif.