ABAP Channels ermöglichen Echtzeit-Kommunikation zwischen ABAP-Anwendungen und Web-Clients. Mit ABAP Messaging Channels (AMC) und ABAP Push Channels (APC) können Push-Nachrichten und WebSocket-Verbindungen implementiert werden.
Channel-Typen
| Typ | Beschreibung |
|---|---|
| AMC | ABAP Messaging Channel - Server-zu-Server |
| APC | ABAP Push Channel - Server-zu-Client (WebSocket) |
ABAP Messaging Channels (AMC)
AMC-Kanal definieren (SAMC)
Transaktion SAMC:1. Kanal-ID: /ZORDER/UPDATES2. Nachrichtentyp: TEXT oder BINARY3. Extension-ID (optional): Für Sub-Channels4. Aktivieren und transportierenNachricht senden
" Einfache Textnachricht sendenTRY. DATA(lo_producer) = cl_amc_channel_manager=>create_message_producer( i_application_id = 'ZORDER_APP' i_channel_id = '/zorder/updates' ).
" Text-Nachricht lo_producer->send( i_message = 'Bestellung 1000000001 wurde aktualisiert' ).
CATCH cx_amc_error INTO DATA(lx_error). MESSAGE lx_error->get_text( ) TYPE 'E'.ENDTRY.Nachricht mit Extension-ID
" Nachricht an spezifischen Sub-ChannelTRY. 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 }| ). " Pro Bestellung
lo_producer->send( i_message = lv_json_message ).
CATCH cx_amc_error INTO DATA(lx_error). MESSAGE lx_error->get_text( ) TYPE 'E'.ENDTRY.Binäre Nachricht senden
" XString-Daten sendenDATA: lv_binary TYPE xstring.
" Daten serialisierenCALL 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 (Empfänger)
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. " Nachricht empfangen DATA(lv_message) = i_message.
" Verarbeitung CASE lv_message. WHEN 'REFRESH'. " UI aktualisieren... WHEN OTHERS. " JSON parsen... ENDCASE. ENDMETHOD.
ENDCLASS.AMC im Background Job
" Nachricht aus Hintergrundprozess sendenREPORT zr_send_amc_notification.
DATA: lv_order_id TYPE zorder_id.
SELECT-OPTIONS: s_order FOR lv_order_id.
START-OF-SELECTION. " Bestellungen verarbeiten SELECT * FROM zorders INTO TABLE @DATA(lt_orders) WHERE order_id IN @s_order.
LOOP AT lt_orders INTO DATA(ls_order). " Verarbeitung...
" Benachrichtigung senden 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( |Bestellung { ls_order-order_id } verarbeitet| ).
CATCH cx_amc_error. " Logging... ENDTRY. ENDLOOP.ABAP Push Channels (APC)
APC-Anwendung definieren (SAPC)
Transaktion SAPC:1. APC-Anwendung: ZORDER_PUSH2. Verbindungsart: WebSocket3. Handler-Klasse: ZCL_ORDER_APC_HANDLER4. Pfad: /sap/bc/apc/zorder5. Aktivieren und transportierenAPC Handler-Klasse
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-Verbindung geöffnet mv_context_id = i_context->get_context_id( ).
" AMC-Consumer für diesen Client starten 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. " Fehlerbehandlung ENDTRY. ENDMETHOD.
METHOD if_apc_wsp_extension~on_message. " Nachricht vom Client empfangen DATA(lv_text) = i_message->get_text( ).
" JSON parsen DATA: ls_request TYPE ty_request. /ui2/cl_json=>deserialize( EXPORTING json = lv_text CHANGING data = ls_request ).
" Request verarbeiten CASE ls_request-action. WHEN 'SUBSCRIBE'. " Client abonniert bestimmte Updates handle_subscribe( ls_request-order_id ).
WHEN 'UNSUBSCRIBE'. handle_unsubscribe( ls_request-order_id ). ENDCASE.
" Antwort senden 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-Verbindung geschlossen " Aufräumen... ENDMETHOD.
METHOD if_apc_wsp_extension~on_error. " Fehler behandeln DATA(lv_error) = i_error->get_text( ). ENDMETHOD.
ENDCLASS.AMC-zu-APC Bridge
" Leitet AMC-Nachrichten an WebSocket-Client weiterCLASS 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. " AMC-Nachricht an WebSocket-Client weiterleiten 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 möglicherweise disconnected ENDTRY. ENDMETHOD.
ENDCLASS.JavaScript WebSocket-Client
// Browser-seitiger WebSocket-Clientconst socket = new WebSocket('wss://server:port/sap/bc/apc/zorder');
// Verbindung geöffnetsocket.onopen = function(event) { console.log('WebSocket verbunden');
// Bestellung abonnieren socket.send(JSON.stringify({ action: 'SUBSCRIBE', order_id: '1000000001' }));};
// Nachricht empfangensocket.onmessage = function(event) { const data = JSON.parse(event.data); console.log('Update erhalten:', data);
// UI aktualisieren updateOrderDisplay(data);};
// Verbindung geschlossensocket.onclose = function(event) { console.log('WebSocket getrennt'); // Reconnect-Logik...};
// Fehlersocket.onerror = function(error) { console.error('WebSocket Fehler:', error);};Broadcast an alle Clients
" Nachricht an alle verbundenen ClientsCLASS 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. " AMC-Nachricht senden (erreicht alle 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. " Fehlerbehandlung ENDTRY. ENDMETHOD.ENDCLASS.Nachricht an spezifischen Client
" Nachricht an bestimmten WebSocket-ClientMETHOD send_to_client. DATA: lv_context_id TYPE apc_context_id.
" Context-ID aus Registry/Tabelle holen lv_context_id = get_client_context( iv_user_id ).
TRY. " Direkter AMC-Kanal mit 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 nicht mehr verbunden ENDTRY.ENDMETHOD.Heartbeat implementieren
" Periodische Ping-NachrichtenMETHOD if_apc_wsp_extension~on_message. DATA(lv_text) = i_message->get_text( ).
IF lv_text = 'PING'. " Pong zurücksenden i_message_manager->send( cl_apc_wsp_message=>create_text( 'PONG' ) ). RETURN. ENDIF.
" Normale Nachrichtenverarbeitung...ENDMETHOD.
" Client-seitig (JavaScript)// Heartbeat alle 30 SekundensetInterval(() => { if (socket.readyState === WebSocket.OPEN) { socket.send('PING'); }}, 30000);Session-Management
" Verbundene Clients trackenCLASS 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.Sichere WebSocket-Verbindung
" APC mit AuthentifizierungMETHOD if_apc_wsp_extension~on_start. " Benutzer prüfen DATA(lv_user) = i_context->get_user( ).
" Berechtigungsprüfung AUTHORITY-CHECK OBJECT 'Z_APC_AUTH' ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0. " Verbindung ablehnen i_context->get_message_manager( )->send( cl_apc_wsp_message=>create_text( '{"error": "Unauthorized"}' ) ).
i_context->close( ). RETURN. ENDIF.
" Normale Verarbeitung...ENDMETHOD.Typische Anwendungsfälle
| Anwendung | Beschreibung |
|---|---|
| Live-Updates | Bestellstatus in Echtzeit |
| Benachrichtigungen | Push-Notifications |
| Chat | Echtzeit-Kommunikation |
| Dashboards | Live-Metriken |
| Collaboration | Gemeinsames Bearbeiten |
Architektur
┌─────────────────┐ ┌─────────────────┐│ 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
- Error Handling: Robuste Fehlerbehandlung für Disconnects
- Heartbeat: Verbindung aktiv halten
- Reconnect: Client-seitige Wiederverbindung
- Security: Authentifizierung und Autorisierung
- Skalierung: Extension-IDs für gezielte Nachrichten
- Logging: Verbindungen und Nachrichten protokollieren
Wichtige Transaktionen
| Transaktion | Beschreibung |
|---|---|
| SAMC | AMC-Kanäle pflegen |
| SAPC | APC-Anwendungen pflegen |
| SMICM | ICM-Monitor (WebSocket) |
Verwandte Themen
- Background Jobs - Hintergrundverarbeitung
- OData Services - REST APIs
- JSON Processing - Nachrichtenformat
- RFC und Destinationen - Server-Kommunikation