Les ABAP Channels permettent la communication en temps reel entre les applications ABAP et les clients web. Avec les ABAP Messaging Channels (AMC) et les ABAP Push Channels (APC), vous pouvez implementer des messages push et des connexions WebSocket.
Types de canaux
| Type | Description |
|---|---|
| AMC | ABAP Messaging Channel - Serveur a serveur |
| APC | ABAP Push Channel - Serveur a client (WebSocket) |
ABAP Messaging Channels (AMC)
Definir un canal AMC (SAMC)
Transaction SAMC :1. ID du canal : /ZORDER/UPDATES2. Type de message : TEXT ou BINARY3. Extension-ID (optionnel) : Pour les sous-canaux4. Activer et transporterEnvoyer un message
" Envoyer un simple message texteTRY. DATA(lo_producer) = cl_amc_channel_manager=>create_message_producer( i_application_id = 'ZORDER_APP" i_channel_id = '/zorder/updates' ).
" Message texte lo_producer->send( i_message = 'Commande 1000000001 a ete mise a jour' ).
CATCH cx_amc_error INTO DATA(lx_error). MESSAGE lx_error->get_text( ) TYPE 'E'.ENDTRY.Message avec Extension-ID
" Message vers un sous-canal specifiqueTRY. 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 }| ). " Par commande
lo_producer->send( i_message = lv_json_message ).
CATCH cx_amc_error INTO DATA(lx_error). MESSAGE lx_error->get_text( ) TYPE 'E'.ENDTRY.Envoyer un message binaire
" Envoyer des donnees XStringDATA: lv_binary TYPE xstring.
" Serialiser les donneesCALL 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 (Recepteur)
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. " Recevoir le message DATA(lv_message) = i_message.
" Traitement CASE lv_message. WHEN 'REFRESH'. " Actualiser l'interface... WHEN OTHERS. " Parser le JSON... ENDCASE. ENDMETHOD.
ENDCLASS.AMC dans un job en arriere-plan
" Envoyer un message depuis un processus d'arriere-planREPORT zr_send_amc_notification.
DATA: lv_order_id TYPE zorder_id.
SELECT-OPTIONS: s_order FOR lv_order_id.
START-OF-SELECTION. " Traiter les commandes SELECT * FROM zorders INTO TABLE @DATA(lt_orders) WHERE order_id IN @s_order.
LOOP AT lt_orders INTO DATA(ls_order). " Traitement...
" Envoyer la 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( |Commande { ls_order-order_id } traitee| ).
CATCH cx_amc_error. " Journalisation... ENDTRY. ENDLOOP.ABAP Push Channels (APC)
Definir une application APC (SAPC)
Transaction SAPC :1. Application APC : ZORDER_PUSH2. Type de connexion : WebSocket3. Classe Handler : ZCL_ORDER_APC_HANDLER4. Chemin : /sap/bc/apc/zorder5. Activer et transporterClasse Handler APC
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. " Connexion WebSocket ouverte mv_context_id = i_context->get_context_id( ).
" Demarrer le consumer AMC pour ce 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. " Gestion des erreurs ENDTRY. ENDMETHOD.
METHOD if_apc_wsp_extension~on_message. " Message recu du client DATA(lv_text) = i_message->get_text( ).
" Parser le JSON DATA: ls_request TYPE ty_request. /ui2/cl_json=>deserialize( EXPORTING json = lv_text CHANGING data = ls_request ).
" Traiter la requete CASE ls_request-action. WHEN 'SUBSCRIBE'. " Le client s'abonne a certaines mises a jour handle_subscribe( ls_request-order_id ).
WHEN 'UNSUBSCRIBE'. handle_unsubscribe( ls_request-order_id ). ENDCASE.
" Envoyer la reponse 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. " Connexion WebSocket fermee " Nettoyage... ENDMETHOD.
METHOD if_apc_wsp_extension~on_error. " Gerer l'erreur DATA(lv_error) = i_error->get_text( ). ENDMETHOD.
ENDCLASS.Pont AMC vers APC
" Transmet les messages AMC au client WebSocketCLASS 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. " Transmettre le message AMC au client WebSocket 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 peut-etre deconnecte ENDTRY. ENDMETHOD.
ENDCLASS.Client JavaScript WebSocket
// Client WebSocket cote navigateurconst socket = new WebSocket('wss://server:port/sap/bc/apc/zorder');
// Connexion ouvertesocket.onopen = function(event) { console.log('WebSocket connecte');
// S'abonner a une commande socket.send(JSON.stringify({ action: 'SUBSCRIBE', order_id: '1000000001" }));};
// Message recusocket.onmessage = function(event) { const data = JSON.parse(event.data); console.log('Mise a jour recue:', data);
// Mettre a jour l'interface updateOrderDisplay(data);};
// Connexion fermeesocket.onclose = function(event) { console.log('WebSocket deconnecte'); // Logique de reconnexion...};
// Erreursocket.onerror = function(error) { console.error('Erreur WebSocket:', error);};Diffusion a tous les clients
" Message a tous les clients connectesCLASS 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. " Envoyer un message AMC (atteint tous les clients APC) cl_amc_channel_manager=>create_message_producer( i_application_id = 'ZORDER_APP" i_channel_id = '/zorder/broadcast" )->send( iv_message ).
CATCH cx_amc_error. " Gestion des erreurs ENDTRY. ENDMETHOD.ENDCLASS.Message a un client specifique
" Message a un client WebSocket specifiqueMETHOD send_to_client. DATA: lv_context_id TYPE apc_context_id.
" Obtenir l'ID de contexte depuis le registre/table lv_context_id = get_client_context( iv_user_id ).
TRY. " Canal AMC direct avec 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 plus connecte ENDTRY.ENDMETHOD.Implementer un Heartbeat
" Messages Ping periodiquesMETHOD if_apc_wsp_extension~on_message. DATA(lv_text) = i_message->get_text( ).
IF lv_text = 'PING'. " Renvoyer Pong i_message_manager->send( cl_apc_wsp_message=>create_text( 'PONG' ) ). RETURN. ENDIF.
" Traitement normal des messages...ENDMETHOD.
" Cote client (JavaScript)// Heartbeat toutes les 30 secondessetInterval(() => { if (socket.readyState === WebSocket.OPEN) { socket.send('PING'); }}, 30000);Gestion des sessions
" Suivre les clients connectesCLASS 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.Connexion WebSocket securisee
" APC avec authentificationMETHOD if_apc_wsp_extension~on_start. " Verifier l'utilisateur DATA(lv_user) = i_context->get_user( ).
" Verification d'autorisation AUTHORITY-CHECK OBJECT 'Z_APC_AUTH" ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0. " Rejeter la connexion i_context->get_message_manager( )->send( cl_apc_wsp_message=>create_text( '{"error": "Unauthorized"}' ) ).
i_context->close( ). RETURN. ENDIF.
" Traitement normal...ENDMETHOD.Cas d’utilisation typiques
| Application | Description |
|---|---|
| Mises a jour en direct | Statut des commandes en temps reel |
| Notifications | Notifications push |
| Chat | Communication en temps reel |
| Tableaux de bord | Metriques en direct |
| Collaboration | Edition collaborative |
Architecture
┌─────────────────┐ ┌─────────────────┐│ Client Web │ │ Client Web ││ (JavaScript) │ │ (JavaScript) │└────────┬────────┘ └────────┬────────┘ │ WebSocket │ WebSocket │ │ ▼ ▼┌─────────────────────────────────────────┐│ ABAP Push Channel ││ (APC Handler) │└────────────────────┬────────────────────┘ │ ▼┌─────────────────────────────────────────┐│ ABAP Messaging Channel ││ (AMC Broker) │└────────────────────┬────────────────────┘ │ ▼┌─────────────────────────────────────────┐│ Logique Backend ABAP ││ (Jobs en arriere-plan, BAPIs, etc.) │└─────────────────────────────────────────┘Bonnes pratiques
- Gestion des erreurs : Gestion robuste des erreurs pour les deconnexions
- Heartbeat : Maintenir la connexion active
- Reconnexion : Reconnexion cote client
- Securite : Authentification et autorisation
- Mise a l’echelle : Extension-IDs pour les messages cibles
- Journalisation : Journaliser les connexions et les messages
Transactions importantes
| Transaction | Description |
|---|---|
| SAMC | Gerer les canaux AMC |
| SAPC | Gerer les applications APC |
| SMICM | Moniteur ICM (WebSocket) |
Sujets connexes
- Jobs en arriere-plan - Traitement en arriere-plan
- Services OData - APIs REST
- Traitement JSON - Format des messages
- RFC et Destinations - Communication serveur