Apache::Session]
Farid Hajji: Perl - Einführung, Anwendungen, Referenz
2., aktualisierte und erweiterte Auflage
Addison-Wesley Longman, ISBN 3-8273-1535-2
Apache::SessionIm Buch haben wir verschiedene Methoden der Zustandserhaltung kennengelernt. Dabei haben wir uns vorallem mit der technischen Realisierung befaßt. Im Wesentlichen geht es darum, die Zustandsvariablen irgendwo zu sichern, damit sie bei einer späteren Invokation des CGI-Programms wiederverwendet werden. Dies war durch folgende Techniken möglich:
PATH_INFOGET-Teil der URLDabei haben wir uns auch damit befaßt, wie die clientseitig gespeicherte Information vor Veränderung (durch Signatur) oder sogar vor unberechtiger Ansicht (durch Verschlüsselung) geschützt werden konnte.
All diese Methoden sind zwar technisch interessant, müssen aber in konkreten Anwendungen erst eingebunden werden. Dabei haben wir versucht, ein einheitliches Framework einzuhalten, das diese Aufgabe erleichern soll. Eine alternative Methode der Zustandserhaltung in professionellen Anwendungen ist das CPAN-Modul Apache::Session. Dieses faßt die oben besprochenen Techniken zusammen und ist auch in seiner Anwendung sehr flexibel. In den folgenden Abschnitten werden wir Apache::Session kennenlernen und anhand kleiner Beispielprogramme sehen, wie einfach dessen Anwendung sein kann.
Apache::Session-Modul und seine VerwendungDas Programm apache-session1.pl orientiert sich in seiner Grundstruktur an die Zustandserhaltungsbeispiele aus dem Buch. Auch wenn es einfacher hätte geschrieben werden können, haben wir die Struktur mit den drei Funktionen retrieve_state(), compute_next_state() und save_state() beibehalten, um die Analogie deutlich zu zeigen.
Schauen wir uns dieses Programm etwas näher an:
cgi-s-server.pl soll der Zustand serverseitig in einer Datenbanktabelle gespeichert werden. Ebenfalls soll die Sitzungs-ID clientseitig mit Hilfe eines Cookies erhalten bleiben.Apache::Session bietet für diesen Zweck die spezialisierte Klasse Apache::Session::DBIStore als Backing-Store an (mehr dazu später). Diese Klasse geht davon aus, daß in einer frei wählbaren Datenbank eine Tabelle namens sessions mit einer ganz bestimmten Struktur vorliegt. Diese Tabelle sollte vor der ersten Verwendung von Apache::Session::DBIStore manuell oder mit Hilfe eines Programms angelegt werden. man Apache::Session::DBIStore gibt uns dabei das Format vor:
farid@sun-1:~> mysql -u nobody -p www
Enter password: wwwpass Unsichtbare Eingabe!
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 29 to server version: 3.22.25
Type 'help' for help.
mysql> drop table sessions;
Query OK, 0 rows affected (0.04 sec)
mysql> create table sessions (
-> id char(16) primary key,
-> length int(11),
-> a_session text);
Query OK, 0 rows affected (0.02 sec)
mysql> \q
Bye
Apache::Session ist äußerst einfach. Wir müssen nur ein Hash an die Klasse Apache::Session::DBIStore binden, wobei wir als Parameter zu tie() die aktuelle Sitzungsnummer oder undef angeben müssen, je nachdem, ob eine solche Sitzung schon bekannt ist oder eine neue Sitzung angelegt werden soll:
use constant STATEDSN => 'dbi:mysql:database=www';
use constant STATEUSER => 'nobody';
use constant STATEPASS => 'wwwpass';
# Cookie gibt eine Session-ID $SID vor:
tie %session, 'Apache::Session::DBI', $SID,
{ DataSource => STATEDSN,
UserName => STATEUSER, Password => STATEPASS }
or die "can't tie: $!\n";
# Das ist eine neue Sitzung!
tie %session, 'Apache::Session::DBI', undef,
{ DataSource => STATEDSN,
UserName => STATEUSER, Password => STATEPASS }
or die "can't tie: $!\n";
%session) gebunden ist, kann es zur Zustandserhaltung verwendet werden, z.B.:
my $SID = $session{'_session_id'}; # Spezielle Kennung fuer die
# aktuelle Sitzungsnummer
my $SVL = $session{'STATE'}; # Die Zustandsvariable 'STATE'
$session{'STATE'} = "newvalue"; # Zustandswert speichern
_session_id und ist im Falle einer neuerzeugten Sitzung wichtig. Sonstige Informationen zum aktuellen Zustand dieser Sitzung sind unter anderen, freiwählbaren Namen in %session zu finden.
STATE in %session serverseitig gespeichert werden:
$SID = $session{'_session_id'}; # Aktuelle Sitzungsnummer
$SVL = $session{'STATE'}; # Aktuelle Seitenzahl
# ... spaeter im Programm:
$session{'STATE'} = $NewSVL; # Neue Seitenzahl speicher!
apache-session1.pl in der Funktion retrieve_state() den Zustand, d.h. die aktuelle Seitennummer, aus $session{'STATE'} extrahiert. Anschließend haben wir mit dieser Information gearbeitet, indem wir sie z.B. in compute_next_state() aktualisiert haben. Diese Aktualisierung erfolgte aber nur im Programm selbst, nicht jedoch auf die Datenbank (d.h. nicht in $session{'STATE'}). Erst nachdem wir fertig waren, speicherten wir den neuen Zustand in der Funktion save_state() in die Datenbank, indem wir an $session{'STATE'} einen neuen Wert zugewiesen haben:
# In retrieve_state():
%localstate = ( SESSION => $session{'_session_id'},
STATE => $session{'STATE'} );
# In compute_next_state():
$localstate{'STATE'} = $localstate{'STATE'} + 1;
# In save_state():
$session{'STATE'} = $localstate{'STATE'};
%session den Wert von $session{'STATE'} zu verändern. Dies wurde hier aus zwei Gründen nicht getan:
retrieve_state(), compute_next_state() und save_state() die Zustandsinformation jeweils nacheinander übergeben.%session) zu speichern. Im vorliegenden Beispiel war das zwar nicht notwendig, aber es gibt durchaus Situationen, in denen der interne Zustand während einer einzigen Programmausführung schnell mehrfach wechselt. In diesem Falle ist es sinnvoller, nur die letzte Änderung in die Datenbank zurückzuspeichern.apache-session1.pl auf die aus cgi-s-server.pl bereits bekannten Art und Weise mit Hilfe eines Cookies. Stattdessen hätten wir auch problemlos die anderen bereits gezeigten Techniken dafür einsetzen können. Versuchen Sie beispielsweise als Übungsaufgabe statt in einem Cookie die Sitzungsnummer clientseitig in PATH_INFO zu sichern!Apache::Session::* ModuleEs scheint zunächst so, daß um Apache::Session zu benutzen, eine DBI-Datenbank unabdingbar wäre. Dem ist jedoch nicht so! Der Grund ist, daß Apache::Session zur Realisierung der Persistenz diverse Backing-Store-Objekte verwenden kann:
Apache::Session::DBIStore zur Speicherung in einer DBI-DatenbanktabelleApache::Session::FileStore zur Speicherung in einer serverseitigen DateiApache::Session::MemoryStore zur Speicherung im serverseitigem Shared-MemoryBei Einsatz eines Backing-Store-Objekts ist es jedoch auch wichtig, die Zugriffe auf die gemeinsame speichernde Ressource zu synchronisieren. Schließlig laufen auf einem Unix-Rechner zu einer bestimmten Zeit durchaus mehrere httpd-Prozesse! Die Synchronisation erfolgt nun mit Hilfe eines Synchnisationsobjekts. Apache::Session kennt mehrere solcher Objekte:
Apache::Session::SysVSemaphoreLocker zur Synchronisation von Prozessen einer einzigen Maschine mittels SemaphorenApache::Session::PosixFileLocker zur Synchronisation mit POSIX-Aufrufen.Apache::Session::DaemonLocker realisiert einen netzwerkweiten Locking-Daemon, der zur Synchronisation von Prozessen auf mehreren Maschinen untereinander verwendet werden kann.Apache::Session::NullLocker synchronisiert gar nichts und kann bei singlethreaded Anwendungen eingesetzt werden.Um nun eine allgemeine Session-Klasse zu erzeugen, kombinieren Sie üblicherweise Apache::Session mit einer Backing-Store-Klasse und einer Synchronisationsklasse Ihrer Wahl. Die in apache-session1.pl verwendete Klasse Apache::Session::DBI ist hierbei lediglich eine Klasse, die sich aus der Basisklasse Apache::Session, der Backing-Store-Klasse Apache::Session::DBIStore sowie der Synchronisationsklasse Apache::Session::SysVSemaphoreLocker wie folgt zusammensetzt:
package Apache::Session::DBI;
use strict;
use vars qw(@ISA $VERSION);
$VERSION = '1.00';
@ISA = qw(Apache::Session);
use Apache::Session;
use Apache::Session::SysVSemaphoreLocker;
use Apache::Session::DBIStore;
sub get_object_store {
my $self = shift;
return new Apache::Session::DBIStore $self;
}
sub get_lock_manager {
my $self = shift;
return new Apache::Session::SysVSemaphoreLocker $self;
}
1;
httpd-Prozessen besteht: DBIStore und SysVSemaphoreLockerDBIStore bzw. MemoryStore und NullLockerDBIStore und DaemonLocker oder bei NFS-Verzeichnissen FileStore und PosixFileLockerDBIStore und DaemonLockerNichts hindert Sie natürlich daran, selbst weitere Backing-Store-- oder Synchronisationsklassen zu spezifizieren und ähnlich mit Apache::Session zu kombinieren.
Apache::Session-1.0.3) bereits vordefininiert:Apache::Session::DBI verwendet DBIStore und SysVSemaphoreLocker.Apache::Session::File verwendet FileStore und SysVSemaphoreLocker.Apache::Session::SingleThread verwendet MemoryStore und NullLocker.Darüberhinaus sind auch die Klassen Apache::Session::Counted und Apache::Session::Tree, sowie den experimentellen Backing-Store Apache::Sessin::TreeStore definiert.
Mehr Informationen finden Sie in man Apache::Session.
[Prev] [Up] [Next]
[Alte Quelle]
| Last modified: $Date: 2006/05/18 12:55:46 $ FH. Search :: Sitemap :: Disclaimer :: Copyright :: Privacy |
|