1.26 ABAP Channels: ABAP Messaging Channels
Programs之间可以通过共享内存分享信息,但是相同系统,不同Application Server之间不能通信;
ABAP Messaging Channels (AMC)提供跨Application通信,结合ABAP Push Channels (APC),可以和外部网络通信,例如:SAP UI5;
Tcode: AMC_LOG_ADMIN,打开Logging;
Tcode: AMC_LOG_PROCESSING,Logging监视器;
Tcode: SMAMC,AMC recipient;
创建AMC方式:
1.使用Tcode:SAMC,可以打开AMC Workbench;
2.使用Tcode:SE80,选择Package->右键Create->Connectivity->ABAP Messaging Channel Applications;
创建一个AMC,通过Application,Channel name区分;
Channel Name:需要/开头,大小写敏感;
Message Type:定义发送Message类型;
TEXT,ABAP类型STRING
Producer interface: IF_AMC_MESSAGE_PRODUCER_TEXT
Receiver interface: IF_AMC_MESSAGE_RECEIVER_TEXT
BINARY,ABAP类型XSTRING
Producer interface: IF_AMC_MESSAGE_PRODUCER_BINARY
Receiver interface: IF_AMC_MESSAGE_RECEIVER_BINARY
PCP, Push Channel Protocol
Corresponding ABAP interface:IF_AC_MESSAGE_TYPE_PCP
Producer interface: IF_AMC_MESSAGE_PRODUCER_PCP
Receiver interface: IF_AMC_MESSAGE_RECEIVER_PCP
定义PCP类型:CL_AC_MESSAGE_TYPE_PCP=>CREATE( );
Scope:定义可以接收Message范围,System,Client,User;
Tcode:SM02,可以看到System中message;
Authorized programs:定义可以接收或发送信息的Program;
Program可以是Reports,Function,Classes;
定义Program: ZTOM_AMC_RECEIVE_TEXT,接收message;
示例代码:
REPORT ZTOM_AMC_RECEIVE_TEXT.
DATA:gt_message_text TYPE TABLE OF string.
SELECTION-SCREEN BEGIN OF BLOCK blk1.
PARAMETERS:p_sec TYPE i. "等待时间
PARAMETERS:p_msgn TYPE i. "message条数
SELECTION-SCREEN END OF BLOCK blk1.
CLASS zcl_amc_receive_text DEFINITION.
PUBLIC SECTION.
INTERFACES if_amc_message_receiver_text.
ENDCLASS.
CLASS zcl_amc_receive_text IMPLEMENTATION.
"实现receive方法
METHOD:if_amc_message_receiver_text~receive.
APPEND i_message TO gt_message_text.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
PERFORM f_get_amc_text.
"获取amc text
FORM f_get_amc_text.
DATA:lo_consumer TYPE REF TO if_amc_message_consumer.
DATA:lo_text_receiver TYPE REF TO zcl_amc_receive_text.
TRY .
"创建msg消费者
lo_consumer = cl_amc_channel_manager=>create_message_consumer(
i_application_id = 'ZT_AMC1'
i_channel_id = '/test'
).
lo_text_receiver = NEW #( ).
"start message delivery
lo_consumer->start_message_delivery(
i_receiver = lo_text_receiver
).
"等待message
WAIT FOR MESSAGING CHANNELS UNTIL
lines( gt_message_text ) >= p_msgn UP TO p_sec SECONDS.
"写出接收message
LOOP AT gt_message_text INTO DATA(gs_message_text).
WRITE:/ gs_message_text.
ENDLOOP.
CATCH cx_root INTO DATA(lo_exception).
WRITE:/ lo_exception->get_text( ).
ENDTRY.
ENDFORM.
定义Program:ZTOM_AMC_SEND_TEXT,发送message;
示例代码:
REPORT ZTOM_AMC_SEND_TEXT.
SELECTION-SCREEN BEGIN OF BLOCK blk1.
PARAMETERS:p_msg TYPE string LOWER CASE. "message
SELECTION-SCREEN END OF BLOCK blk1.
AT SELECTION-SCREEN.
PERFORM f_send_amc_text.
"发送amc text
FORM f_send_amc_text.
DATA:lo_producer TYPE REF TO if_amc_message_producer_text.
TRY.
"创建msg消费者
lo_producer ?= cl_amc_channel_manager=>create_message_producer(
i_application_id = 'ZT_AMC1'
i_channel_id = '/test'
).
lo_producer->send( i_message = p_msg ).
CATCH cx_root INTO DATA(lo_exception).
WRITE:/ lo_exception->get_text( ).
ENDTRY.
ENDFORM.
示例Package:SABAPDEMOS,Application:DEMO_AMC;
示例代码: CL_AMC_CHANNEL_MANAGER,AMC Channel管理类,message生产者;
FORM f_amc_send_message.
DATA:lo_producer TYPE REF TO if_amc_message_producer_text.
TRY.
lo_producer ?= cl_amc_channel_manager=>create_message_producer(
i_application_id = 'DEMO_AMC'
i_channel_id = '/demo_text'
).
lo_producer->send( 'test message' ).
CATCH cx_root INTO DATA(lo_exception).
WRITE:/ lo_exception->get_text( ).
ENDTRY.
ENDFORM.
获取Message Consumer,可以自定义类,通过实现接口IF_AMC_MESSAGE_RECEIVER_<message_type>,定义receiver;
示例代码:
"message consumer
FORM f_amc_get_message.
DATA:lo_consumer TYPE REF TO if_amc_message_consumer.
TRY.
lo_consumer = cl_amc_channel_manager=>create_message_consumer(
i_application_id = 'DEMO_AMC'
i_channel_id = '/demo_text'
).
CATCH cx_root INTO DATA(lo_exception).
WRITE:/ lo_exception->get_text( ).
ENDTRY.
ENDFORM.
示例代码:Receiver类定义
"AMC reveiver类定义
CLASS zcl_receiver DEFINITION.
PUBLIC SECTION.
INTERFACES: if_amc_message_receiver_text.
EVENTS message_received EXPORTING VALUE(ev_message) TYPE string.
ENDCLASS.
CLASS zcl_receiver IMPLEMENTATION.
METHOD:if_amc_message_receiver_text~receive.
RAISE EVENT message_received EXPORTING ev_message = i_message.
ENDMETHOD.
ENDCLASS.
"使用receiver
FORM f_amc_receiver.
DATA:lo_receiver TYPE REF TO zcl_receiver.
DATA:lo_consumer TYPE REF TO if_amc_message_consumer.
TRY.
lo_consumer = cl_amc_channel_manager=>create_message_consumer(
i_application_id = 'DEMO_AMC'
i_channel_id = '/demo_text'
).
"CREATE OBJECT lo_receiver.
lo_receiver = NEW #( ).
lo_consumer->start_message_delivery( lo_receiver ).
CATCH cx_root INTO DATA(lo_exception).
WRITE:/ lo_exception->get_text( ).
ENDTRY.
ENDFORM.
示例代码:等待AMC信息;
"wait 语句
FORM f_amc_wait.
"WAIT FOR MESSAGING CHANNELS UNTIL <condition> UP TO <n> SECONDS.
ENDFORM.
1.27 ABAP Channels: ABAP Push Channels
A Web Service can push data to ABAP Program;
ABAP Program Push Message to a web page;
使用Tcode:SAPC,可以打开APC Workbench;
右键->Create->输入Application名称;
Class Name:ZCL_APC_WSP_EXT_ZT_APC1;
点击Generate Class and Service;
Connection Type:可以设置链接类型,WebSocket或者TCP Socket;
Protocol:可以设置协议;
选择重写ON_START方法,ON_MESSAGE方法;
示例代码:
method IF_APC_WSP_EXTENSION~ON_START.
*CALL METHOD SUPER->IF_APC_WSP_EXTENSION~ON_START
* EXPORTING
* I_CONTEXT =
* I_MESSAGE_MANAGER =
* .
TRY.
" send the message on websocket connection
DATA(lo_message) = i_message_manager->create_message( ).
lo_message->set_text( |{ sy-mandt }/{ sy-uname }: ON_START has been successfully executed !| ).
i_message_manager->send( lo_message ).
CATCH cx_apc_error INTO DATA(lx_apc_error).
MESSAGE lx_apc_error->get_text( ) TYPE 'E'.
ENDTRY.
endmethod.
示例代码:
method IF_APC_WSP_EXTENSION~ON_MESSAGE.
*CALL METHOD SUPER->IF_APC_WSP_EXTENSION~ON_MESSAGE
* EXPORTING
* I_MESSAGE =
* I_MESSAGE_MANAGER =
* I_CONTEXT =
* .
TRY.
" retrieve the text message
DATA(lv_text) = i_message->get_text( ).
" create the message manager and message object
DATA(lo_message) = i_message_manager->create_message( ).
" send 1st message
lo_message->set_text( |{ sy-mandt }/{ sy-uname }: ON_MESSAGE has been successfully executed !| ).
i_message_manager->send( lo_message ).
" send 2nd message, i.e. echo the incoming message
lo_message->set_text( lv_text ).
i_message_manager->send( lo_message ).
CATCH cx_apc_error INTO DATA(lx_apc_error).
MESSAGE lx_apc_error->get_text( ) TYPE 'E'.
ENDTRY.
endmethod.
保存Class激活后,点击执行;
弹出Web页面;
WDA Component:WDR_TEST_APC_WSP
如何AMC和APC一起使用,实现Web发送信息给ABAP Program,ABAP Program发送信息给Web?
1.修改APC中的on_start,on_message方法;
示例代码:on_start
TRY.
"start时绑定为消费者,接收ABAP program message
DATA(lo_binding) = i_context->get_binding_manager( ).
lo_binding->bind_amc_message_consumer(
i_application_id = 'ZT_AMC1'
i_channel_id = '/test'
).
CATCH cx_apc_error INTO DATA(lo_exception).
MESSAGE lo_exception->get_text( ) TYPE 'E'.
ENDTRY.
示例代码:on_message
"案例2
"作为producer,生成message给ABAP program
TRY .
DATA:lo_producer TYPE REF TO if_amc_message_producer_text.
DATA(lv_text) = i_message->get_text( ).
lo_producer ?= cl_amc_channel_manager=>create_message_producer(
i_application_id = 'ZT_AMC1'
i_channel_id = '/test'
).
lo_producer->send( i_message = lv_text ).
CATCH cx_amc_error INTO DATA(lo_amc_exception).
MESSAGE lo_amc_exception->get_text( ) TYPE 'E'.
CATCH cx_apc_error INTO DATA(lo_apc_exception).
MESSAGE lo_apc_exception->get_text( ) TYPE 'E'.
ENDTRY.
2.将APC对应Class,维护为AMC的Authorized Program;
3.执行测试APC
通过Web发送信息,然后Program: ZTOM_AMC_RECEIVE_TEXT接收信息;
通过Program: ZTOM_AMC_SEND_TEXT发送信息,Web接收信息;
参考Blog:
https://blogs.sap.com/2015/09/07/abap-push-channel-messaging-channel-and-sapui5-demo-application/