Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

Introduction

Using stateful BSP applications poses an obvious problem: how do we remove the server state for browser based application. If the user navigates outside of our application or shuts down their browser, our server state remains, consuming valuable system resources. For a while now BSP programmers have had the option of routing the start of their applications through a copy of a one of two pages in the SYSTEM BSP Application.



We have the pages session_single_frame.htm and session_buffered_frame.htm. Single Frame can be used under normal conditions and buffered frame is used for when your application uses delta handling. These pages show you how you can load your application into a frame. You then register a JavaScript function to fire on the OnUnLoad event of this fameset. This JavaScript function then launches a popup window that will clear up your applications current server state.



The Problem

If you have tried this solution, then you know that it works reasonable well under most situations. So what is the problem? First it uses a popup window. To most end users, popup windows that fire without their triggering an action are as bad as SPAM. The situation has become so serious, that we have popup blockers being built into just about every internet browser. Before you know it, you have some user who doesn't know how to set a popup exception calling your support desk wanting to know why the record he was working on before break says that he still has it locked. I have even seen an Internet Explorer Patch that broke IE's ability to render output into the popup. You end up with a nice empty popup window and a mountain of dead stateful sessions back on your server. Let's just say that the day that patch rolled out, we had lots of grouchy support desk technicians.



The Solution

Well now that my name is mud with the local support desk, what can I do to redeem myself. Lucky SAP has come to the rescue with a new solution to the state management problem. An example of this new solution is available in BSP application ITSM as of 620 SP44 or 640 (not sure what SP it introduced in for 640 - however it is there in SP9). Now don't fret if you aren't quite at the latest support package. Most of the functionality in this solution is JavaScript. I was able to get the coding from a 640 sandbox system and then successfully use it in our 620 SP42 system. The only thing I can tell you is to give it a try and see what happens.



The main difference between the two solutions is that the new one doesn't rely on popup boxes to destroy the session state. Instead it uses some special functionality built into the ICM to close the session. The following is an explanation of how the ICM works to accomplish this that Brian McKellar shared a while back in a related subject. I will just quote him here again, since he explains it better than I ever could.

The ICM supports a sap-sessioncmd=CANCEL mode. With this, the session is killed by ICM, and then the incoming URL is still processed inside a new session. We just require an URL that looks exactly like the application URL in the part up to the name of the application, so that the session id cookie will be send with it. After ICM has cancelled the session, the URL will still be processed. So we require an URL that will be processed by the BSP runtime without any problems (and without opening a new session!). For this, we just use a special 1x1 URL. The BSP runtime has a performance improvement that will always reply with a 1x1.gif for an incoming URL of the format ".../1x1". However, this 1x1 image is cached, and the trick will only work once. So we just add one timestamp to make the URL unique for the browser, and have it trigger the loading of the 1x1 image.</p>

This solution as explained is very much what makes up the new logon session management.  What SAP does is in JavaScript is create an Image that refers to the 1x1.gif but also passes on the URL the Context ID and the Session Command CANCEL.  The following are those two lines of JavaScript:</p>

<textarea rows="4" cols="79">
img=new Image;
img.src = document.location.href+"/1x1.gif?sap-contextid=<%=
cl_http_utility=>escape_url( runtime->server->session_id ) %>
&sap-sessioncmd=CANCEL";

</textarea></p>

<STRONG><FONT size=3>The Sample</FONT></STRONG><br>
Incase you don't have the required support package level to see the example in ITSM, the following is a sample page that uses this solution:</p>
<textarea rows="10" cols="79">
<%@page language="abap" %>
<%@extension name="htmlb" prefix="htmlb" %>
<%@extension name="xhtmlb" prefix="xhtmlb" %>
<%@extension name="phtmlb" prefix="phtmlb" %>
<%
  " Copy this page into your BSP application, and change line below.
  " This page should always used be as entry point into application.
  DATA: target_page TYPE STRING VALUE 'index.do'.
  DATA: frame       type string.
  frame = sy-uzeit.
%>

            <script language="JavaScript">
      <%= runtime->GET_DOMAIN_RELAX_SCRIPT( )  %>
      // Delete the cookie with the specified name.
      function DelSso2Cookie(sName,sPath)
      {
          var sso2Domain = location.hostname;
          if (location.hostname.indexOf(".")>
0)

              sso2Domain = location.hostname.substr(location.hostname.indexOf(".")+1);

          p="";

          if(sPath)p=" path="sPath";";

              document.cookie = sName"=0; expires=Fri, 31 Dec 1999 23:59:59 GMT;"p + "domain="sso2Domain";";

      }

      function exitBSPApplication(newTargetUrl)

      {

<%

  if runtime->session_manager->is_running = 0.

%>

img=new Image;

img.src = document.location.href+"/1x1.gif?sap-contextid=<%= cl_http_utility=>escape_url( runtime->server->session_id ) %>&sap-sessioncmd=CANCEL";

<%

  " If you want to destroy the SSO2 cookie along with the server session,

  " please uncomment the function below

%>

//DelSso2Cookie("MYSAPSSO2","/");

for(i=0;i<5000;i++)for(e in document.all) tmp=e.innerHTML;

<%

  endif.

%>

          document.getElementById("<%= frame %>_FRAMESET").onunload = null;

          if(newTargetUrl) window.setTimeout('{document.location.href="'newTargetUrl'";}', 750);

      }

     

0)`

              `sso2Domain = location.hostname.substr(location.hostname.indexOf(".")+1);`

          `p="";`

          `if(sPath)p=" path="sPath";";`

              `document.cookie = sName"=0; expires=Fri, 31 Dec 1999 23:59:59 GMT;"p + "domain="sso2Domain";";`

      `}`

   into html.

****Begin Exit Function

  concatenate html

   `function exitBSPApplication(newTargetUrl)`

     `{`

  into html.

****Log Off Action

  if mc_runtime->session_manager->is_running = 0.

    data: context_id type string.

    data: session_id type string.

    session_id = mc_runtime->server->session_id.

    context_id = cl_http_utility=>escape_url( session_id ).

    concatenate html

        `img=new Image;`

        `img.src = document.location.href+"/1x1.gif?sap-contextid=`

         context_id

        `&sap-sessioncmd=CANCEL";`

         into html.

****Delete SSO2 Cookie?

    if destroysso2cookie = abap_true.

      concatenate html

      `DelSso2Cookie("MYSAPSSO2","/");`

      into html.

    endif.

    concatenate html

       `for(i=0;i<5000;i++)for(e in document.all) tmp=e.innerHTML;`

       into html.

  endif.

****Build the Frame

  concatenate html

         `document.getElementById("`

         frame

         `_FRAMESET").onunload = null;`

         `if(newTargetUrl) window.setTimeout('{document.location.href="'newTargetUrl'";}', 750);`

     `}`

     ``
into html.

****Display the FrameSets
concatenate html
``
`

25 Comments