ABAP Channels permiten la comunicación en tiempo real entre aplicaciones ABAP y clientes web. Con ABAP Messaging Channels (AMC) y ABAP Push Channels (APC) se pueden implementar mensajes push y conexiones WebSocket.
Tipos de Channels
| Tipo | Descripción |
|---|---|
| AMC | ABAP Messaging Channel - Servidor a servidor |
| APC | ABAP Push Channel - Servidor a cliente (WebSocket) |
ABAP Messaging Channels (AMC)
Definir canal AMC (SAMC)
Transacción SAMC:1. ID de canal: /ZORDER/UPDATES2. Tipo de mensaje: TEXT o BINARY3. Extension-ID (opcional): Para sub-canales4. Activar y transportarEnviar mensaje
" Enviar mensaje de texto simpleTRY. DATA(lo_producer) = cl_amc_channel_manager=>create_message_producer( i_application_id = 'ZORDER_APP' i_channel_id = '/zorder/updates' ).
" Mensaje de texto lo_producer->send( i_message = 'Pedido 1000000001 actualizado' ).
CATCH cx_amc_error INTO DATA(lx_error). MESSAGE lx_error->get_text( ) TYPE 'E'.ENDTRY.Mensaje con Extension-ID
" Mensaje a sub-canal específicoTRY. 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 }| ). " Por pedido
lo_producer->send( i_message = lv_json_message ).
CATCH cx_amc_error INTO DATA(lx_error). MESSAGE lx_error->get_text( ) TYPE 'E'.ENDTRY.Enviar mensaje binario
" Enviar datos XStringDATA: lv_binary TYPE xstring.
" Serializar datosCALL 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 (Receptor)
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. " Recibir mensaje DATA(lv_message) = i_message.
" Procesamiento CASE lv_message. WHEN 'REFRESH'. " Actualizar UI... WHEN OTHERS. " Parsear JSON... ENDCASE. ENDMETHOD.
ENDCLASS.AMC en Job de Fondo
" Enviar mensaje desde proceso de fondoREPORT zr_send_amc_notification.
DATA: lv_order_id TYPE zorder_id.
SELECT-OPTIONS: s_order FOR lv_order_id.
START-OF-SELECTION. " Procesar pedidos SELECT * FROM zorders INTO TABLE @DATA(lt_orders) WHERE order_id IN @s_order.
LOOP AT lt_orders INTO DATA(ls_order). " Procesamiento...
" Enviar notificación 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( |Pedido { ls_order-order_id } procesado| ).
CATCH cx_amc_error. " Logging... ENDTRY. ENDLOOP.ABAP Push Channels (APC)
Definir aplicación APC (SAPC)
Transacción SAPC:1. Aplicación APC: ZORDER_PUSH2. Tipo de conexión: WebSocket3. Clase Handler: ZCL_ORDER_APC_HANDLER4. Ruta: /sap/bc/apc/zorder5. Activar y transportarClase 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. " Conexión WebSocket abierta mv_context_id = i_context->get_context_id( ).
" Iniciar AMC-Consumer para este cliente 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. " Manejo de errores ENDTRY. ENDMETHOD.
METHOD if_apc_wsp_extension~on_message. " Mensaje recibido del cliente DATA(lv_text) = i_message->get_text( ).
" Parsear JSON DATA: ls_request TYPE ty_request. /ui2/cl_json=>deserialize( EXPORTING json = lv_text CHANGING data = ls_request ).
" Procesar request CASE ls_request-action. WHEN 'SUBSCRIBE'. " Cliente suscribe a actualizaciones específicas handle_subscribe( ls_request-order_id ).
WHEN 'UNSUBSCRIBE'. handle_unsubscribe( ls_request-order_id ). ENDCASE.
" Enviar respuesta 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. " Conexión WebSocket cerrada " Limpieza... ENDMETHOD.
METHOD if_apc_wsp_extension~on_error. " Manejar error DATA(lv_error) = i_error->get_text( ). ENDMETHOD.
ENDCLASS.Bridge AMC a APC
" Reenvía mensajes AMC al cliente 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. " Reenviar mensaje AMC al cliente 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. " Cliente posiblemente desconectado ENDTRY. ENDMETHOD.
ENDCLASS.Cliente WebSocket JavaScript
// Cliente WebSocket del lado del navegadorconst socket = new WebSocket('wss://server:port/sap/bc/apc/zorder');
// Conexión abiertasocket.onopen = function(event) { console.log('WebSocket conectado');
// Suscribirse a pedido socket.send(JSON.stringify({ action: 'SUBSCRIBE', order_id: '1000000001' }));};
// Mensaje recibidosocket.onmessage = function(event) { const data = JSON.parse(event.data); console.log('Actualización recibida:', data);
// Actualizar UI updateOrderDisplay(data);};
// Conexión cerradasocket.onclose = function(event) { console.log('WebSocket desconectado'); // Lógica de reconexión...};
// Errorsocket.onerror = function(error) { console.error('Error WebSocket:', error);};Broadcast a todos los clientes
" Mensaje a todos los clientes conectadosCLASS 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. " Enviar mensaje AMC (alcanza todos los clientes 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. " Manejo de errores ENDTRY. ENDMETHOD.ENDCLASS.Mensaje a cliente específico
" Mensaje a cliente WebSocket específicoMETHOD send_to_client. DATA: lv_context_id TYPE apc_context_id.
" Obtener Context-ID del registro/tabla lv_context_id = get_client_context( iv_user_id ).
TRY. " Canal AMC directo con 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. " Cliente ya no conectado ENDTRY.ENDMETHOD.Implementar Heartbeat
" Mensajes Ping periódicosMETHOD if_apc_wsp_extension~on_message. DATA(lv_text) = i_message->get_text( ).
IF lv_text = 'PING'. " Enviar Pong i_message_manager->send( cl_apc_wsp_message=>create_text( 'PONG' ) ). RETURN. ENDIF.
" Procesamiento normal de mensajes...ENDMETHOD.
" Del lado del cliente (JavaScript)// Heartbeat cada 30 segundossetInterval(() => { if (socket.readyState === WebSocket.OPEN) { socket.send('PING'); }}, 30000);Gestión de sesiones
" Rastrear clientes conectadosCLASS 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.Conexión WebSocket segura
" APC con autenticaciónMETHOD if_apc_wsp_extension~on_start. " Verificar usuario DATA(lv_user) = i_context->get_user( ).
" Verificación de autorización AUTHORITY-CHECK OBJECT 'Z_APC_AUTH' ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0. " Rechazar conexión i_context->get_message_manager( )->send( cl_apc_wsp_message=>create_text( '{"error": "Unauthorized"}' ) ).
i_context->close( ). RETURN. ENDIF.
" Procesamiento normal...ENDMETHOD.Casos de uso típicos
| Aplicación | Descripción |
|---|---|
| Actualizaciones en vivo | Estado de pedidos en tiempo real |
| Notificaciones | Notificaciones push |
| Chat | Comunicación en tiempo real |
| Dashboards | Métricas en vivo |
| Colaboración | Edición colaborativa |
Arquitectura
┌─────────────────┐ ┌─────────────────┐│ Cliente Web │ │ Cliente Web ││ (JavaScript) │ │ (JavaScript) │└────────┬────────┘ └────────┬────────┘ │ WebSocket │ WebSocket │ │ ▼ ▼┌─────────────────────────────────────────┐│ ABAP Push Channel ││ (APC Handler) │└────────────────────┬────────────────────┘ │ ▼┌─────────────────────────────────────────┐│ ABAP Messaging Channel ││ (AMC Broker) │└────────────────────┬────────────────────┘ │ ▼┌─────────────────────────────────────────┐│ Lógica Backend ABAP ││ (Jobs de fondo, BAPIs, etc.) │└─────────────────────────────────────────┘Mejores prácticas
- Manejo de errores: Manejo robusto de desconexiones
- Heartbeat: Mantener conexión activa
- Reconexión: Reconexión del lado del cliente
- Seguridad: Autenticación y autorización
- Escalabilidad: Extension-IDs para mensajes dirigidos
- Logging: Registrar conexiones y mensajes
Transacciones importantes
| Transacción | Descripción |
|---|---|
| SAMC | Gestionar canales AMC |
| SAPC | Gestionar aplicaciones APC |
| SMICM | Monitor ICM (WebSocket) |
Temas relacionados
- Jobs de fondo - Procesamiento en segundo plano
- Servicios OData - APIs REST
- Procesamiento JSON - Formato de mensajes
- RFC y Destinos - Comunicación entre servidores