From b3749f0477728ddb4438d823a6fc00df73ab0379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Christian?= Date: Tue, 25 Nov 2025 16:55:23 +0000 Subject: [PATCH] restore WS sample --- src/00/z2ui5_cl_demo_app_s_05.clas.abap | 188 ++++++++++++++++++++- src/00/z2ui5_cl_demo_app_s_05.clas.xml | 14 +- src/00/z2ui5_cl_demo_app_s_05_ws.clas.abap | 108 +++++++++++- src/00/z2ui5_cl_demo_app_s_05_ws.clas.xml | 14 +- src/00/z2ui5_sample.samc.xml | 4 +- src/00/z2ui5_sample.sapc.xml | 2 +- 6 files changed, 311 insertions(+), 19 deletions(-) diff --git a/src/00/z2ui5_cl_demo_app_s_05.clas.abap b/src/00/z2ui5_cl_demo_app_s_05.clas.abap index 597292a4..5c6de4a6 100644 --- a/src/00/z2ui5_cl_demo_app_s_05.clas.abap +++ b/src/00/z2ui5_cl_demo_app_s_05.clas.abap @@ -1,13 +1,187 @@ -class Z2UI5_CL_DEMO_APP_S_05 definition - public - create public . +CLASS z2ui5_cl_demo_app_s_05 DEFINITION PUBLIC. + + PUBLIC SECTION. + + TYPES: + BEGIN OF t_news, + text TYPE string, + author TYPE string, + END OF t_news, + tt_News TYPE STANDARD TABLE OF t_news + WITH NON-UNIQUE DEFAULT KEY. + + INTERFACES z2ui5_if_app. + DATA news_input TYPE string. + DATA author_input TYPE string. + DATA news_list TYPE tt_News. + DATA connections TYPE int8. + + PROTECTED SECTION. + DATA client TYPE REF TO z2ui5_if_client. + + METHODS z2ui5_on_event. + METHODS z2ui5_on_render. + METHODS z2ui5_display_popover. + + PRIVATE SECTION. -public section. -protected section. -private section. ENDCLASS. +CLASS z2ui5_cl_demo_app_s_05 IMPLEMENTATION. + + METHOD z2ui5_if_app~main. + + me->client = client. + + IF me->z2ui5_if_app~check_initialized = abap_false. + connections = z2ui5_cl_demo_app_s_05_ws=>get_active_connections( ). + ENDIF. + + IF client->get( )-event IS NOT INITIAL. + z2ui5_on_event( ). + client->view_model_update( ). + RETURN. + ENDIF. + + z2ui5_on_render( ). + + ENDMETHOD. + + + METHOD z2ui5_on_event. + DATA: news TYPE t_news. + + CASE client->get( )-event. + WHEN `CLEAR`. + + CLEAR: news_list. + + WHEN 'BACK'. + + client->nav_app_leave( client->get_app( client->get( )-s_draft-id_prev_app_stack ) ). + + WHEN 'CLICK_HINT_ICON'. + + z2ui5_display_popover( ). + + ENDCASE. + + ENDMETHOD. + + + METHOD z2ui5_on_render. + + DATA(view) = z2ui5_cl_xml_view=>factory( ). + DATA(page) = view->shell( + )->page( + title = 'abap2UI5 - Sample: News Feed over WebSocket' + navbuttonpress = client->_event( 'BACK' ) + shownavbutton = xsdbool( client->get( )-s_draft-id_prev_app_stack IS NOT INITIAL ) ). + + page->header_content( + )->button( id = `button_hint_id` + icon = `sap-icon://hint` + tooltip = `Sample information` + press = client->_event( 'CLICK_HINT_ICON' ) ). + + DATA(form) = page->simple_form( editable = abap_true + title = `Publish news` + class = `sapUiTinyMarginBottom` + )->content( `form` ). + + form->feed_input( + value = client->_bind_edit( news_input ) + post = client->_event_client( + val = `Z2UI5` + t_arg = VALUE #( ( `feedInputPost` ) ) + ) ). + + form->label( text = `Author` + )->input( value = client->_bind_edit( author_input ) + placeholder = `Anonymous` ). + + page->list( + headertext = `News` + items = client->_bind_edit( news_list ) + )->feed_list_item( + sender = `{AUTHOR}` + text = `{TEXT}` + showicon = abap_false ). + + DATA(footer) = page->footer( )->overflow_toolbar( ). + footer->info_label( + text = client->_bind_edit( connections ) + colorscheme = `7` + icon = `sap-icon://connected` ). + + footer->toolbar_spacer( )->button( + text = `Clear` + icon = `sap-icon://clear-all` + press = client->_event( `CLEAR` ) ). + + IF me->z2ui5_if_app~check_initialized = abap_false. + view->_generic( name = `script` + ns = `html` + )->_cc_plain_xml( + `(()=>{ ` && + ` const ws_url = (window.location.origin + '/sap/bc/apc/sap/z2ui5_sample').replace('http','ws');` && + ` try { ` && + ` ws = new WebSocket(ws_url);` && + ` } catch (err) {` && + ` alert(err);` && + ` }` && + ` ws.onopen = ()=>{};` && + ` ws.onmessage = (msg)=>{` && + ` const model = z2ui5.oController.oView.getModel();` && + ` const data = model.getData();` && + ` if (msg.data === '` && z2ui5_cl_demo_app_s_05_ws=>c_msg-__new_connection__ && `') {` && + ` data.XX.CONNECTIONS += 1;` && + ` } else if (msg.data === '` && z2ui5_cl_demo_app_s_05_ws=>c_msg-__closed__ && `') {` && + ` data.XX.CONNECTIONS -= 1;` && + ` } else {` && + ` data.XX.NEWS_LIST.push(JSON.parse(msg.data));` && + ` }` && + ` model.setData(data);` && + ` };` && + ` ws.onclose = (msg)=>{};` && + `})()` ). + + view->_generic( name = `script` + ns = `html` + )->_cc_plain_xml( + `z2ui5.feedInputPost = () => { ` && + ` const model = z2ui5.oView.getModel();` && + ` const data = model.getData();` && + ` ws.send(JSON.stringify({ ` && + ` TEXT : data.XX.NEWS_INPUT,` && + ` AUTHOR : data.XX.AUTHOR_INPUT ` && + ` }));` && + ` setTimeout( () => { ` && + ` data.XX.NEWS_INPUT = "";` && + ` model.setData(data);` && + ` }, 10 ); ` && + `}` ). + ENDIF. + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + + METHOD z2ui5_display_popover. + + DATA(view) = z2ui5_cl_xml_view=>factory_popup( ). + view->quick_view( placement = `Bottom` + width = `auto` + )->quick_view_page( pageid = `sampleInformationId` + header = `Sample information` + description = `This sample show how to consume APC-Messages over websocket. Open the app mutliple times and post something.` ). + + client->popover_display( + xml = view->stringify( ) + by_id = `button_hint_id` ). + + ENDMETHOD. -CLASS Z2UI5_CL_DEMO_APP_S_05 IMPLEMENTATION. ENDCLASS. diff --git a/src/00/z2ui5_cl_demo_app_s_05.clas.xml b/src/00/z2ui5_cl_demo_app_s_05.clas.xml index 4a1b746e..25a51505 100644 --- a/src/00/z2ui5_cl_demo_app_s_05.clas.xml +++ b/src/00/z2ui5_cl_demo_app_s_05.clas.xml @@ -1,4 +1,16 @@  - + + + + Z2UI5_CL_DEMO_APP_S_05 + E + News Feed over Websocket + 1 + X + X + X + + + diff --git a/src/00/z2ui5_cl_demo_app_s_05_ws.clas.abap b/src/00/z2ui5_cl_demo_app_s_05_ws.clas.abap index b470bc66..289c0556 100644 --- a/src/00/z2ui5_cl_demo_app_s_05_ws.clas.abap +++ b/src/00/z2ui5_cl_demo_app_s_05_ws.clas.abap @@ -1,13 +1,107 @@ -class Z2UI5_CL_DEMO_APP_S_05_WS definition - public - create public . +CLASS z2ui5_cl_demo_app_s_05_ws DEFINITION PUBLIC + INHERITING FROM cl_apc_wsp_ext_stateless_base. + + PUBLIC SECTION. + + CLASS-METHODS: get_active_connections + RETURNING + VALUE(result) TYPE i. + + METHODS: + if_apc_wsp_extension~on_message REDEFINITION, + if_apc_wsp_extension~on_start REDEFINITION, + if_apc_wsp_extension~on_close REDEFINITION. + + CONSTANTS: + c_amc_application_id TYPE amc_application_id VALUE 'Z2UI5_SAMPLE' ##NO_TEXT, + c_channel_id TYPE amc_channel_id VALUE '/news_feed' ##NO_TEXT, + BEGIN OF c_msg, + __new_connection__ TYPE string VALUE `__NEW_CONNECTION__` ##NO_TEXT, + __closed__ TYPE string VALUE `__CLOSED__` ##NO_TEXT, + END OF c_msg. + + PRIVATE SECTION. + + CLASS-METHODS: + get_producer + RETURNING + VALUE(producer) TYPE REF TO if_amc_message_producer_text + RAISING + cx_amc_error, + send + IMPORTING + i_message TYPE string + RAISING + cx_amc_error. -public section. -protected section. -private section. ENDCLASS. +CLASS z2ui5_cl_demo_app_s_05_ws IMPLEMENTATION. + + METHOD get_producer. + + producer ?= cl_amc_channel_manager=>create_message_producer( i_application_id = c_amc_application_id + i_channel_id = c_channel_id ). + + ENDMETHOD. + + + METHOD if_apc_wsp_extension~on_message. + + TRY. + send( i_message->get_text( ) ). + CATCH cx_root INTO DATA(error). + RAISE SHORTDUMP error. + ENDTRY. + + ENDMETHOD. + + + METHOD if_apc_wsp_extension~on_start. + + TRY. + + i_context->get_binding_manager( + )->bind_amc_message_consumer( i_application_id = c_amc_application_id + i_channel_id = c_channel_id ). + + get_producer( )->send( c_msg-__new_connection__ ). + + CATCH cx_root INTO DATA(error). + RAISE SHORTDUMP error. + ENDTRY. + + ENDMETHOD. + + + METHOD if_apc_wsp_extension~on_close. + + TRY. + get_producer( )->send( c_msg-__closed__ ). + + CATCH cx_root INTO DATA(error). + RAISE SHORTDUMP error. + ENDTRY. + + ENDMETHOD. + + + METHOD get_active_connections. + + SELECT + FROM amc_receiver2 + FIELDS COUNT( * ) + WHERE channel_id = @( to_lower( |{ c_amc_application_id }{ c_channel_id }| ) ) + INTO @result. + + ENDMETHOD. + + + METHOD send. + + get_producer( )->send( i_message ). + + ENDMETHOD. -CLASS Z2UI5_CL_DEMO_APP_S_05_WS IMPLEMENTATION. ENDCLASS. diff --git a/src/00/z2ui5_cl_demo_app_s_05_ws.clas.xml b/src/00/z2ui5_cl_demo_app_s_05_ws.clas.xml index 4a1b746e..88a8a13d 100644 --- a/src/00/z2ui5_cl_demo_app_s_05_ws.clas.xml +++ b/src/00/z2ui5_cl_demo_app_s_05_ws.clas.xml @@ -1,4 +1,16 @@  - + + + + Z2UI5_CL_DEMO_APP_S_05_WS + E + Generated APC WebSocket protocol impementation class + 1 + X + X + X + + + diff --git a/src/00/z2ui5_sample.samc.xml b/src/00/z2ui5_sample.samc.xml index d5b0bc3c..15a48b4e 100644 --- a/src/00/z2ui5_sample.samc.xml +++ b/src/00/z2ui5_sample.samc.xml @@ -28,7 +28,7 @@ A 1 /news_feed - Z2UI5_CL_DEMO_APP_352_WS======CP + Z2UI5_CL_DEMO_APP_S_05_WS=====CP S @@ -36,7 +36,7 @@ A 2 /news_feed - Z2UI5_CL_DEMO_APP_352_WS======CP + Z2UI5_CL_DEMO_APP_S_05_WS=====CP C diff --git a/src/00/z2ui5_sample.sapc.xml b/src/00/z2ui5_sample.sapc.xml index a9e5ece1..8f9c505b 100644 --- a/src/00/z2ui5_sample.sapc.xml +++ b/src/00/z2ui5_sample.sapc.xml @@ -7,7 +7,7 @@ Z2UI5_SAMPLE A /sap/bc/apc/sap/z2ui5_sample - Z2UI5_CL_DEMO_APP_352_WS + Z2UI5_CL_DEMO_APP_S_05_WS 1