ABAP Channels: Push Notifications and Real-Time Communication

Category
ABAP-Statements
Published
Author
Johannes

ABAP Channels enable real-time communication between ABAP applications and web clients. With ABAP Messaging Channels (AMC) and ABAP Push Channels (APC), push notifications and WebSocket connections can be implemented.

Channel Types

TypeDescription
AMCABAP Messaging Channel - Server-to-Server
APCABAP Push Channel - Server-to-Client (WebSocket)

ABAP Messaging Channels (AMC)

Define AMC Channel (SAMC)

Transaction SAMC:
1. Channel ID: /ZORDER/UPDATES
2. Message type: TEXT or BINARY
3. Extension ID (optional): For sub-channels
4. Activate and transport

Send Message

" Send simple text message
TRY.
DATA(lo_producer) = cl_amc_channel_manager=>create_message_producer(
i_application_id = 'ZORDER_APP'
i_channel_id = '/zorder/updates' ).
" Text message
lo_producer->send( i_message = 'Order 1000000001 has been updated' ).
CATCH cx_amc_error INTO DATA(lx_error).
MESSAGE lx_error->get_text( ) TYPE 'E'.
ENDTRY.

Message with Extension ID

" Message to specific sub-channel
TRY.
DATA(lo_producer) = cl_amc_channel_manager=>create_message_producer(
i_application_id = 'ZORDER_APP'
i_channel_id = '/zorder/updates'
i_extension_id = |ORDER_{ lv_order_id }| ). " Per order
lo_producer->send( i_message = lv_json_message ).
CATCH cx_amc_error INTO DATA(lx_error).
MESSAGE lx_error->get_text( ) TYPE 'E'.
ENDTRY.

Send Binary Message

" Send XString data
DATA: lv_binary TYPE xstring.
" Serialize data
CALL TRANSFORMATION id
SOURCE data = ls_order_data
RESULT XML lv_binary.
TRY.
DATA(lo_producer) = cl_amc_channel_manager=>create_message_producer_bin(
i_application_id = 'ZORDER_APP'
i_channel_id = '/zorder/binary' ).
lo_producer->send( i_message = lv_binary ).
CATCH cx_amc_error INTO DATA(lx_error).
MESSAGE lx_error->get_text( ) TYPE 'E'.
ENDTRY.

AMC Consumer (Receiver)

CLASS zcl_order_amc_consumer DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_amc_message_receiver.
METHODS start_listening.
ENDCLASS.
CLASS zcl_order_amc_consumer IMPLEMENTATION.
METHOD start_listening.
TRY.
cl_amc_channel_manager=>create_message_consumer(
i_application_id = 'ZORDER_APP'
i_channel_id = '/zorder/updates'
)->start_message_delivery( i_receiver = me ).
CATCH cx_amc_error INTO DATA(lx_error).
MESSAGE lx_error->get_text( ) TYPE 'E'.
ENDTRY.
ENDMETHOD.
METHOD if_amc_message_receiver~receive.
" Receive message
DATA(lv_message) = i_message.
" Processing
CASE lv_message.
WHEN 'REFRESH'.
" Update UI...
WHEN OTHERS.
" Parse JSON...
ENDCASE.
ENDMETHOD.
ENDCLASS.

AMC in Background Job

" Send message from background process
REPORT zr_send_amc_notification.
DATA: lv_order_id TYPE zorder_id.
SELECT-OPTIONS: s_order FOR lv_order_id.
START-OF-SELECTION.
" Process orders
SELECT * FROM zorders INTO TABLE @DATA(lt_orders)
WHERE order_id IN @s_order.
LOOP AT lt_orders INTO DATA(ls_order).
" Processing...
" Send notification
TRY.
cl_amc_channel_manager=>create_message_producer(
i_application_id = 'ZORDER_APP'
i_channel_id = '/zorder/updates'
i_extension_id = |ORDER_{ ls_order-order_id }|
)->send( |Order { ls_order-order_id } processed| ).
CATCH cx_amc_error.
" Logging...
ENDTRY.
ENDLOOP.

ABAP Push Channels (APC)

Define APC Application (SAPC)

Transaction SAPC:
1. APC Application: ZORDER_PUSH
2. Connection type: WebSocket
3. Handler class: ZCL_ORDER_APC_HANDLER
4. Path: /sap/bc/apc/zorder
5. Activate and transport

APC Handler Class

CLASS zcl_order_apc_handler DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_apc_wsp_extension.
PRIVATE SECTION.
DATA: mv_context_id TYPE apc_context_id.
ENDCLASS.
CLASS zcl_order_apc_handler IMPLEMENTATION.
METHOD if_apc_wsp_extension~on_start.
" WebSocket connection opened
mv_context_id = i_context->get_context_id( ).
" Start AMC consumer for this client
TRY.
cl_amc_channel_manager=>create_message_consumer(
i_application_id = 'ZORDER_APP'
i_channel_id = '/zorder/updates'
)->start_message_delivery(
i_receiver = NEW zcl_apc_amc_bridge( i_context ) ).
CATCH cx_amc_error.
" Error handling
ENDTRY.
ENDMETHOD.
METHOD if_apc_wsp_extension~on_message.
" Message received from client
DATA(lv_text) = i_message->get_text( ).
" Parse JSON
DATA: ls_request TYPE ty_request.
/ui2/cl_json=>deserialize(
EXPORTING json = lv_text
CHANGING data = ls_request ).
" Process request
CASE ls_request-action.
WHEN 'SUBSCRIBE'.
" Client subscribes to specific updates
handle_subscribe( ls_request-order_id ).
WHEN 'UNSUBSCRIBE'.
handle_unsubscribe( ls_request-order_id ).
ENDCASE.
" Send response
DATA(lv_response) = /ui2/cl_json=>serialize(
data = VALUE ty_response( status = 'OK' ) ).
i_message_manager->send( i_message = cl_apc_wsp_message=>create_text( lv_response ) ).
ENDMETHOD.
METHOD if_apc_wsp_extension~on_close.
" WebSocket connection closed
" Cleanup...
ENDMETHOD.
METHOD if_apc_wsp_extension~on_error.
" Handle error
DATA(lv_error) = i_error->get_text( ).
ENDMETHOD.
ENDCLASS.

AMC-to-APC Bridge

" Forwards AMC messages to WebSocket client
CLASS zcl_apc_amc_bridge DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_amc_message_receiver.
METHODS constructor
IMPORTING io_apc_context TYPE REF TO if_apc_wsp_context.
PRIVATE SECTION.
DATA: mo_context TYPE REF TO if_apc_wsp_context.
ENDCLASS.
CLASS zcl_apc_amc_bridge IMPLEMENTATION.
METHOD constructor.
mo_context = io_apc_context.
ENDMETHOD.
METHOD if_amc_message_receiver~receive.
" Forward AMC message to WebSocket client
TRY.
DATA(lo_message) = cl_apc_wsp_message=>create_text( i_message ).
mo_context->get_message_manager( )->send( lo_message ).
CATCH cx_apc_error.
" Client possibly disconnected
ENDTRY.
ENDMETHOD.
ENDCLASS.

JavaScript WebSocket Client

// Browser-side WebSocket client
const socket = new WebSocket('wss://server:port/sap/bc/apc/zorder');
// Connection opened
socket.onopen = function(event) {
console.log('WebSocket connected');
// Subscribe to order
socket.send(JSON.stringify({
action: 'SUBSCRIBE',
order_id: '1000000001'
}));
};
// Message received
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('Update received:', data);
// Update UI
updateOrderDisplay(data);
};
// Connection closed
socket.onclose = function(event) {
console.log('WebSocket disconnected');
// Reconnect logic...
};
// Error
socket.onerror = function(error) {
console.error('WebSocket Error:', error);
};

Broadcast to All Clients

" Message to all connected clients
CLASS zcl_order_notifier DEFINITION.
PUBLIC SECTION.
CLASS-METHODS notify_all
IMPORTING iv_message TYPE string.
ENDCLASS.
CLASS zcl_order_notifier IMPLEMENTATION.
METHOD notify_all.
TRY.
" Send AMC message (reaches all APC clients)
cl_amc_channel_manager=>create_message_producer(
i_application_id = 'ZORDER_APP'
i_channel_id = '/zorder/broadcast'
)->send( iv_message ).
CATCH cx_amc_error.
" Error handling
ENDTRY.
ENDMETHOD.
ENDCLASS.

Message to Specific Client

" Message to specific WebSocket client
METHOD send_to_client.
DATA: lv_context_id TYPE apc_context_id.
" Get context ID from registry/table
lv_context_id = get_client_context( iv_user_id ).
TRY.
" Direct AMC channel with extension
cl_amc_channel_manager=>create_message_producer(
i_application_id = 'ZORDER_APP'
i_channel_id = '/zorder/direct'
i_extension_id = lv_context_id
)->send( iv_message ).
CATCH cx_amc_error.
" Client no longer connected
ENDTRY.
ENDMETHOD.

Implement Heartbeat

" Periodic ping messages
METHOD if_apc_wsp_extension~on_message.
DATA(lv_text) = i_message->get_text( ).
IF lv_text = 'PING'.
" Send pong back
i_message_manager->send(
cl_apc_wsp_message=>create_text( 'PONG' ) ).
RETURN.
ENDIF.
" Normal message processing...
ENDMETHOD.
" Client-side (JavaScript)
// Heartbeat every 30 seconds
setInterval(() => {
if (socket.readyState === WebSocket.OPEN) {
socket.send('PING');
}
}, 30000);

Session Management

" Track connected clients
CLASS zcl_apc_session_manager DEFINITION.
PUBLIC SECTION.
CLASS-DATA: gt_sessions TYPE TABLE OF ty_session.
CLASS-METHODS register
IMPORTING iv_context_id TYPE apc_context_id
iv_user_id TYPE sy-uname.
CLASS-METHODS unregister
IMPORTING iv_context_id TYPE apc_context_id.
CLASS-METHODS get_sessions_for_user
IMPORTING iv_user_id TYPE sy-uname
RETURNING VALUE(rt_sessions) TYPE ty_session_tab.
ENDCLASS.
CLASS zcl_apc_session_manager IMPLEMENTATION.
METHOD register.
APPEND VALUE #(
context_id = iv_context_id
user_id = iv_user_id
timestamp = sy-datum && sy-uzeit
) TO gt_sessions.
ENDMETHOD.
METHOD unregister.
DELETE gt_sessions WHERE context_id = iv_context_id.
ENDMETHOD.
METHOD get_sessions_for_user.
rt_sessions = VALUE #( FOR session IN gt_sessions
WHERE ( user_id = iv_user_id ) ( session ) ).
ENDMETHOD.
ENDCLASS.

Secure WebSocket Connection

" APC with authentication
METHOD if_apc_wsp_extension~on_start.
" Check user
DATA(lv_user) = i_context->get_user( ).
" Authorization check
AUTHORITY-CHECK OBJECT 'Z_APC_AUTH'
ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0.
" Reject connection
i_context->get_message_manager( )->send(
cl_apc_wsp_message=>create_text( '{"error": "Unauthorized"}' ) ).
i_context->close( ).
RETURN.
ENDIF.
" Normal processing...
ENDMETHOD.

Typical Use Cases

ApplicationDescription
Live UpdatesOrder status in real-time
NotificationsPush notifications
ChatReal-time communication
DashboardsLive metrics
CollaborationCollaborative editing

Architecture

┌─────────────────┐ ┌─────────────────┐
│ Web Client │ │ Web Client │
│ (JavaScript) │ │ (JavaScript) │
└────────┬────────┘ └────────┬────────┘
│ WebSocket │ WebSocket
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ ABAP Push Channel │
│ (APC Handler) │
└────────────────────┬────────────────────┘
┌─────────────────────────────────────────┐
│ ABAP Messaging Channel │
│ (AMC Broker) │
└────────────────────┬────────────────────┘
┌─────────────────────────────────────────┐
│ ABAP Backend Logic │
│ (Background Jobs, BAPIs, etc.) │
└─────────────────────────────────────────┘

Best Practices

  1. Error Handling: Robust error handling for disconnects
  2. Heartbeat: Keep connection alive
  3. Reconnect: Client-side reconnection
  4. Security: Authentication and authorization
  5. Scaling: Extension IDs for targeted messages
  6. Logging: Log connections and messages

Important Transactions

TransactionDescription
SAMCMaintain AMC channels
SAPCMaintain APC applications
SMICMICM Monitor (WebSocket)