# Schließen des Browserfensters/-tabs erkennen?



## nebulo (23. Jun 2007)

Ich habe folgendes Problem bei meinem Content Management System. Ich sperre eine Resource sobald sie von einem Benutzer geladen wird. Damit wird sichergestellt das nicht eine Resource von mehreren editiert wird und dann gegenseiteitig die Änderungen überschrieben werden. 

Nun ist mein Problem das wenn das Broswerfenster bzw. das Tab geschlossen wird die Resource nicht wieder freigegen wird. 

Hat jemand eine Idee wie ich dieses Problem lösen könnte? 

Zur eingesetzten Technologie: Ich benutze GWT und POJO's (Kommunikation über RPC). Alles läuft im Tomcat.

Gruß nebulo


----------



## WeirdAl (23. Jun 2007)

Hi,
der Browser meldet Dir nicht das der Nutzer das Fenster geschlossen hast. Damit Du einen "Deadlock" vermeidest, könnt est Du den Nutzer dazu veranlassen bzw. nötigen einen bestimmten Knopf zu drücken, um die Resource wieder freizugeben. Vielleicht wäre die "Emulation" eines modalen Dialogs eine Idee, damit der Nutzer eigentlich nur die Möglichkeit hat, den Dialog wegzu-x-en oder einen Schliessen Button zu drücken.

Ich hoffe ich konnte Dir n bissl weiterhelfen 

Cu
Alex


----------



## nebulo (23. Jun 2007)

Ja natürlich könnte ich sowas machen. Ich hab dann allerdings immer noch das Problem, dass ich den Benutzer nicht zwingen kann den ich nenne ihn mal Logout-Knopf zu benutzen. Ich kann schließlich nicht verhindern, dass der Benutzer das Browserfenster einfach schließt.


----------



## Czapie (23. Jun 2007)

Ich bin mir im Moment gerade nicht sicher, ob man dem Tomcat Anweisungen geben kann, was zu tun, wenn eine Session von der Zeit her "abläuft", denn da ist sie ja immer. Wenn es dabei Möglichkeiten gibt würde ich das empfehlen.

Wenn nicht, dann kannst du diesen Mechanismus nachempfinden:

- Möchte ein Benutzer ein Eintrag/Objekt/was auch immer editieren, könntest du prüfen ob die Sperrung 20 Minuten (oder so= zurückliegt und wenn ja dann das Objekt für den Anfragenden freigeben.


----------



## nebulo (23. Jun 2007)

Dann werde ich das mal so lösen und mich zunächst informieren  ob es eine Möglichkeit gibt das Sessionende als event oder ähnliches vom ServletContainer zu bekommen. Ansonsten wird das nämlich recht aufwändig ^^ .

Danke für die Beiträge schonmal!


----------



## VuuRWerK (23. Jun 2007)

Es gibt noch ein JavaScript-Event was ausgelöst wird wenn ein Dokument verlassen wird. Also entweder das Fenster/Tab geschlossen oder aber auch durch klicken auf einen Link wo das Dokument verlassen wird und ein neues geöffnet wird wird der Event ausgelöst.

Der Event nennt sich "onunload" und sollte am besten im body-Tag angewendet werden.

Bsp:

```
<body onunload="onUnloadHandler()">
```

Die Funktion "onUnloadHandler()" sollte dann eine Ajax-Funktion sein welche das laden einer Seite übernimmt und dort die nötigen Einstellungen übernimmt um die Ressource wieder frei zugeben.

Gut Schuß
VuuRWerK


----------



## nebulo (23. Jun 2007)

Hört sich gut an! Mir ist zwar nicht ganz klar wie das dann aussehen sollte. Aber ich werde mal in die Richtung suchen und experimentieren.


----------



## VuuRWerK (23. Jun 2007)

Naja Du hast eben das onunload im Body-Tag(eleganter wäre es auch erst vom javascript einfügen zulassen, denn wenn das geht ist auch JS aktiviert) und dann erstellst Du mithilfe von Ajax eine Funktion mit der Du dann eine .jsp aufrufst in welcher Du dann den Code ausführst um die editierten Ressourcen wieder frei zugeben.

Gut Schuß
VuuRWerK


----------



## nebulo (24. Jun 2007)

Ja vom Prinzip her scheint es ja nicht allzu schwierig zu sein das umzustzen. Mir ist nur noch nicht ganz klar wie ich das mit dem GWT hinbekommen. Aber ich werde es mal versuchen. 

Danke für die Tipps.

Edit:

Ich bin nun soweit, dass beim schließen des Fensters per alert() eine Messagebox ausgeben wird. Ich habe jedoch auch versucht eine andere Seite per:

document.location.href="http://www.neueadresse.de";

oder 

window.location.replace('http://www.neueadresse.de');

zu öffnen was ja nötig sein wird um eine die JSP aufzurufen leider scheint das nicht zu funktionieren. 


Gruß nebulo


----------



## VuuRWerK (24. Jun 2007)

Nein das funktioniert natürlich dann so nicht mehr. Daher hab ich ja gesagt das Du es mit Ajax machen sollst. Mit Ajax ist das Aufrufen von Scripten möglich, ohne jedoch die Hyperreferenz(href) des Browsers zu ändern. Quasi ein Submit ohne neuladen der Seite.

Hier ein Bsp:


```
function getAjaxRequest() {
    if(window.XMLHttpRequest) {
        http = new XMLHttpRequest();
        if(http.overrideMimeType("text/html")) {
            http = null;
        }
    } else if(window.ActiveXObject) {
        try {
            http = new ActiveXObject("Msxml2.XMLHTTP");
        } catch(ex) {
            try {
                http = new ActiveXObject("Microsoft.XMLHTTP");
            } catch(ex2) {
                http = null;
            }
        }
    }
    return(http);
}

var http = getAjaxRequest();

function onUnloadHandler() {
    if(http == null) {
        alert("Your Browser does not Support Ajax!");
    }
    var params = "id=1&do=delete";   // for example
    http.onreadystatechange = onReadyStateChangedCallback;
    http.open("POST", "http://www.example.com/scripts/doanything.jsp", true);
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Content-length", params.length);
    http.setRequestHeader("Connection", "close");
    http.send(params);
}

function onReadyStateChangedCallback() {
    if(http.readyState == 4) {
        if(http.status == 200) {
            alert("Delete!");
            var scriptOutput = http.responseText;
        } else {
            alert("Something goes wrong! Http-Status: " + http.status);
        }
    }
}
```

Hab es aus meinem eigenem Ajax-Mini-Framework rauskopiert, sollte es also Probleme geben dann bitte bescheid geben.

Gut Schuß
VuuRWerK


----------



## nebulo (24. Jun 2007)

Ich kenne mich leider sowohl mit JavaScript und auch Ajax noch nicht so gut aus. ^^ Meinst du es würde so funktionieren? 
Ich setzte GWT ein. D.h. ich habe so nicht allzuviel mit JS am Hut.


```
<html>
<head>




<title>CMS</title>




<link rel="stylesheet" href="cms.css">





<meta name='gwt:module' content='de.cms.view.MainView'>
<script type="text/javascript">
		function getAjaxRequest() {
   			if(window.XMLHttpRequest) {
				http = new XMLHttpRequest();
        		if(http.overrideMimeType("text/html")) {
			    	http = null;
			    }
	  	  	} else if(window.ActiveXObject) {
        		try {
		            http = new ActiveXObject("Msxml2.XMLHTTP");
        		} catch(ex) {
	            	try {
    	            	http = new ActiveXObject("Microsoft.XMLHTTP");
        	    	} catch(ex2) {
                		http = null;
	           		}
		        }
    		}
	    	return(http);
		}

		var http = getAjaxRequest();

		function onUnloadHandler() {
		    if(http == null) {
        		alert("Your Browser does not Support Ajax!");
		    }
		    var params = "id=1&do=delete";   // for example
		    http.onreadystatechange = onReadyStateChangedCallback;
		    http.open("POST", "http://www.example.com/scripts/logout.jsp", true);
		    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		    http.setRequestHeader("Content-length", params.length);
		    http.setRequestHeader("Connection", "close");
		    http.send(params);
		}

		function onReadyStateChangedCallback() {
		    if(http.readyState == 4) {
        		if(http.status == 200) {
		            alert("Delete!");
        		    var scriptOutput = http.responseText;
		        } else {
        	   		alert("Something goes wrong! Http-Status: " + http.status);
        		}
		    }
		}
		</script>
</head>






<body onunload="onUnloadHandler()">






<script language="javascript" src="gwt.js"></script>


<iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>

<table align=center>
	<tr>
		<td id="slot1"></td>
	</tr>
</table>
</body>
</html>
```


----------



## VuuRWerK (24. Jun 2007)

Ich denke so sollte es funktionieren. Denke aber daran die Variable "params" noch zu ändern und zwar so das Du mithilfe der jsp Deine Ressource wieder freigibst. Übergebe bspw die id der Ressource, innerhalb des jsp musst Du dann das post auslesen um auf die id zugreifen zu können. Natürlich darfst Du auch nicht vergessen die URL zu Deinem Script zu ändern 

Gut Schuß
VuuRWerK


----------



## nebulo (24. Jun 2007)

Ok, vielen Dank für die Hilfe!

Ich denke ich werde das jetzt hinbekommen.

Ich werde denke ich mit onload eine id erzeuegn um nachher die Resourcen zu identifizieren die dann freigegeben werden.


----------



## VuuRWerK (24. Jun 2007)

Du kannst dem unloadhandler auch eine id mitgeben als Parameter und damit dann den param-String zusammen basteln.

Gut Schuß
VuuRWerK


----------

