Pendahuluan
Dalam lingkungan tanpa kewarganegaraan seperti aplikasi Web, memahami konsep status sesi tidak memiliki arti sebenarnya. Meskipun demikian, manajemen negara yang efektif adalah fitur yang harus dimiliki oleh sebagian besar aplikasi Web. Microsoft ASP.NET, serta banyak lingkungan pemrograman sisi server lainnya, menyediakan lapisan abstraksi yang memungkinkan aplikasi menyimpan data persisten berdasarkan per pengguna dan per aplikasi.
Penting untuk dicatat bahwa status sesi aplikasi web adalah data yang di-cache dan diambil oleh aplikasi di berbagai permintaan. Sesi mewakili semua permintaan yang dikirim oleh pengguna saat terhubung ke situs, dan status sesi adalah kumpulan data persisten yang dihasilkan dan dikonsumsi oleh pengguna selama sesi tersebut. Status setiap sesi tidak bergantung satu sama lain dan tidak ada lagi saat sesi pengguna berakhir.
Status sesi tidak memiliki korespondensi dengan entitas logis mana pun yang membentuk protokol dan spesifikasi HTTP. Sesi adalah lapisan abstraksi yang dibangun oleh lingkungan pengembangan sisi server seperti ASP tradisional dan ASP.NET. Cara ASP.NET menampilkan status sesi dan bagaimana status sesi diimplementasikan secara internal bergantung pada infrastruktur platform. Oleh karena itu, ASP tradisional dan ASP.NET mengimplementasikan status sesi dengan cara yang sangat berbeda, dan perbaikan serta penyempurnaan lebih lanjut diharapkan terjadi pada versi ASP.NET berikutnya.
Artikel ini membahas cara mengimplementasikan status sesi di ASP.NET 1.1 dan cara mengoptimalkan manajemen status sesi di aplikasi Web yang dikelola.
Ikhtisar Status Sesi ASP.NET
Status sesi bukan bagian dari infrastruktur HTTP. Artinya, harus ada komponen struktural yang mengikat status sesi dengan setiap permintaan masuk. Lingkungan runtime (ASP tradisional atau ASP.NET) dapat menerima kata kunci seperti Sesi dan menggunakannya untuk menunjukkan blok data yang disimpan di server. Agar berhasil menyelesaikan panggilan ke objek Sesi, lingkungan runtime harus menambahkan status sesi ke konteks panggilan dari permintaan yang sedang diproses. Cara melakukan hal ini berbeda-beda antar platform, namun hal ini penting untuk aplikasi web stateful.
Dalam ASP tradisional, status sesi diimplementasikan sebagai objek COM berulir bebas yang terdapat di perpustakaan asp.dll. (Apakah Anda penasaran? CLSID objek ini sebenarnya adalah D97A6DA0-A865-11cf-83AF-00A0C90C2BD8.) Objek ini menyimpan data yang disusun sebagai kumpulan pasangan nama/nilai. Placeholder "nama" mewakili kunci yang digunakan untuk mengambil informasi, sedangkan placeholder "nilai" mewakili apa yang disimpan dalam status sesi. Pasangan nama/nilai dikelompokkan berdasarkan ID sesi sehingga setiap pengguna hanya melihat pasangan nama/nilai yang dia buat.
Di ASP.NET, antarmuka pemrograman untuk status sesi hampir sama dengan ASP tradisional. Namun implementasi dasarnya sangat berbeda. Sebelum kita mempelajari status sesi ASP.NET, mari kita tinjau secara singkat beberapa kemampuan struktural infrastruktur sesi ASP.NET.
Di ASP.NET, setiap permintaan HTTP yang masuk disalurkan melalui modul HTTP. Setiap modul dapat menyaring dan mengubah sejumlah besar informasi yang dibawa oleh permintaan. Informasi yang terkait dengan setiap permintaan disebut "konteks panggilan", yang diwakili oleh objek HttpContext dalam pemrograman. Kita tidak boleh menganggap konteks permintaan sebagai wadah informasi negara lainnya, meskipun kumpulan Item yang disediakannya hanyalah wadah data. Objek HttpContext berbeda dari semua objek status lainnya (misalnya, Sesi, Aplikasi, dan Cache) karena memiliki masa pakai terbatas melebihi waktu yang diperlukan untuk menangani permintaan. Ketika permintaan melewati serangkaian modul HTTP terdaftar, objek HttpContext-nya akan berisi referensi ke objek status. Ketika permintaan akhirnya dapat diproses, konteks panggilan terkait terikat ke sesi tertentu (Sesi) dan objek status global (Aplikasi dan Cache).
Modul HTTP yang bertanggung jawab untuk mengatur status sesi setiap pengguna adalah SessionStateModule. Struktur modul ini dirancang berdasarkan antarmuka IHttpModule, yang menyediakan sejumlah besar layanan terkait status sesi untuk aplikasi ASP.NET. Termasuk pembuatan ID sesi, pengelolaan sesi tanpa cookie, pengambilan data sesi dari penyedia status eksternal, dan pengikatan data ke konteks panggilan permintaan.
Modul HTTP tidak menyimpan data sesi secara internal. Status sesi selalu disimpan dalam komponen eksternal yang disebut "penyedia status". Penyedia negara sepenuhnya merangkum data status sesi dan berkomunikasi dengan bagian lain melalui metode antarmuka IStateClientManager. Modul HTTP status sesi memanggil metode pada antarmuka ini untuk membaca dan menyimpan status sesi. ASP.NET 1.1 mendukung tiga penyedia negara yang berbeda, seperti yang ditunjukkan pada Tabel 1.
Tabel 1:Deskripsi Penyedia
Penyedia Klien Status
Nilai sesi InProc tetap menjadi objek aktif dalam memori proses pekerja ASP.NET (aspnet_wp.exe atau w3wp.exe di Microsoft® Windows Server® 2003). Ini adalah opsi default.
Nilai sesi StateServer diserialkan dan disimpan dalam memori dalam proses terpisah (aspnet_state.exe). Prosesnya juga dapat berjalan di komputer lain.
Nilai sesi SQLServer diserialkan dan disimpan dalam tabel Microsoft® SQL Server®. Contoh SQL Server dapat dijalankan secara lokal atau jarak jauh.
Modul HTTP status sesi membaca penyedia status yang dipilih saat ini dari bagian <sessionState> pada file web.config.
<sessionState mode="InProc | StateServer | SQLServer />;
Bergantung pada nilai atribut mode, status sesi akan diambil dan disimpan dalam proses berbeda melalui langkah berbeda. Secara default, status sesi disimpan di lokal Proses pekerja ASP.NET. Dalam kasus khusus, ini disimpan dalam slot khusus objek ASP.NET Cache (tidak dapat diakses secara terprogram). Status sesi juga dapat disimpan secara eksternal, bahkan dalam proses jarak jauh (Misalnya, di Windows Layanan NT bernama aspnet_state.exe). Opsi ketiga adalah menyimpan status sesi dalam tabel database khusus yang dikelola oleh SQL Server 2000.
Modul HTTP membatalkan serialisasi nilai sesi di awal permintaan, menjadikannya objek kamus (sebenarnya objek bertipe HttpSessionState) kemudian diakses secara terprogram melalui properti Session yang diekspos oleh kelas (misalnya, HttpContext dan Page). Pengikatan berlangsung hingga permintaan berakhir. Jika permintaan berhasil diselesaikan, semua nilai status akan diserialkan kembali ke penyedia status dan tersedia untuk permintaan lainnya.
Gambar 1 mengilustrasikan komunikasi antara halaman ASP.NET yang diminta dan nilai sesi. Kode yang digunakan oleh setiap halaman terkait dengan atribut Session pada kelas halaman sama dengan ASP tradisional.
Gambar 1: Arsitektur status sesi di ASP.NET 1.1
Nilai fisik status sesi dikunci selama waktu yang diperlukan untuk menyelesaikan permintaan. Kunci ini dikelola secara internal oleh modul HTTP dan digunakan untuk menyinkronkan akses ke status sesi.
Modul status sesi membuat instance penyedia status aplikasi dan menginisialisasinya dengan informasi yang dibaca dari file web.config. Selanjutnya, setiap penyedia akan melanjutkan operasi inisialisasinya masing-masing. Tergantung pada jenis penyedia, operasi inisialisasinya akan sangat bervariasi. Misalnya, manajer status SQL Server akan membuka koneksi ke database tertentu, sedangkan manajer di luar proses akan memeriksa port TCP yang ditentukan. Di sisi lain, manajer status InProc akan menyimpan referensi ke fungsi panggilan balik. Tindakan ini dilakukan ketika sebuah elemen dihapus dari cache dan digunakan untuk memicu kejadian Session_OnEnd aplikasi.
Akses sinkron ke status sesi
Apa yang terjadi ketika halaman Web melakukan panggilan yang sangat sederhana dan intuitif ke properti Session? Banyak operasi yang dilakukan di latar belakang, seperti yang ditunjukkan dalam kode rumit berikut:
int siteCount = Convert.ToInt32(Session["Counter"]);
Kode di atas sebenarnya mengakses nilai sesi yang dibuat oleh modul HTTP di memori lokal Replika membaca data dari penyedia negara tertentu (lihat Gambar 1). Apa yang terjadi jika halaman lain juga mencoba mengakses status sesi secara sinkron? Dalam hal ini, permintaan saat ini mungkin berhenti memproses data yang tidak konsisten atau basi. Untuk menghindari hal ini, modul status sesi akan menerapkan mekanisme penguncian pembaca/penulis dan akses antrean ke nilai status. Halaman dengan izin menulis pada status sesi akan mempertahankan kunci penulis untuk sesi tersebut hingga permintaan dihentikan.
Sebuah halaman dapat meminta izin menulis untuk status sesi dengan mengatur properti EnableSessionState dari direktif @Page ke true. (Ini adalah pengaturan default). Namun, halaman juga dapat memiliki akses baca-saja ke status sesi, misalnya, ketika properti EnableSessionState diatur ke ReadOnly. Dalam hal ini, modul akan mempertahankan kunci pembaca untuk sesi tersebut hingga permintaan untuk halaman tersebut berakhir. Akibatnya pembacaan bersamaan akan terjadi.
Jika permintaan halaman menyetel kunci pembaca, permintaan bersamaan lainnya dalam sesi yang sama tidak akan dapat memperbarui status sesi, namun setidaknya dapat membaca. Artinya, jika permintaan baca-saja sedang diproses untuk suatu sesi, permintaan hanya-baca yang tertunda akan memiliki prioritas lebih tinggi daripada permintaan yang memerlukan akses penuh. Jika permintaan halaman menetapkan kunci penulis untuk status sesi, semua halaman lainnya akan diblokir terlepas dari apakah mereka ingin membaca atau menulis konten. Misalnya, jika dua frame mencoba menulis ke Sesi pada saat yang sama, satu frame harus menunggu hingga frame lainnya selesai sebelum dapat menulis.
Membandingkan Penyedia Negara
Secara default, aplikasi ASP.NET menyimpan status sesi dalam memori proses pekerja, khususnya di slot khusus objek Cache. Ketika mode InProc dipilih, status sesi disimpan dalam slot di dalam objek Cache. Slot ini ditandai sebagai slot pribadi dan tidak dapat diakses secara terprogram. Dengan kata lain, jika Anda menghitung semua item dalam cache data ASP.NET, tidak ada objek yang serupa dengan status sesi tertentu yang akan dikembalikan. Objek cache menyediakan dua jenis slot: slot pribadi dan slot publik. Pemrogram dapat menambahkan dan menangani slot publik, namun slot pribadi hanya dapat digunakan oleh sistem (khususnya, kelas yang ditentukan di bagian system.web).
Status setiap sesi aktif menempati slot khusus di cache. Slot diberi nama berdasarkan ID sesi, dan nilainya adalah turunan dari kelas internal yang tidak dideklarasikan bernama SessionStateItem. Penyedia status InProc mendapatkan ID sesi dan mengambil elemen terkait di cache. Isi dari objek SessionStateItem kemudian dimasukkan ke dalam objek kamus HttpSessionState dan diakses oleh aplikasi melalui properti Session. Perhatikan bahwa ada bug di ASP.NET 1.0 yang membuat slot pribadi objek Cache dapat dihitung secara terprogram. Jika Anda menjalankan kode berikut di bawah ASP.NET 1.0, Anda akan dapat menghitung item yang sesuai dengan objek yang terdapat dalam setiap status sesi yang sedang aktif.
foreach(Elemen Entri Kamus di Cache)
{
Response.Write(elem.Key + ": " + elem.Value.ToString());
}
Bug ini telah diatasi di ASP.NET 1.1 dan ketika Anda menghitung konten cache, tidak ada slot sistem yang akan dicantumkan lagi.
InProc mungkin merupakan opsi akses tercepat sejauh ini. Namun perlu diingat bahwa semakin banyak data yang disimpan dalam satu sesi, semakin banyak memori yang dikonsumsi server web, sehingga berpotensi meningkatkan risiko penurunan kinerja. Jika Anda berencana menggunakan solusi di luar proses, Anda harus mempertimbangkan dengan cermat kemungkinan efek serialisasi dan deserialisasi. Solusi di luar proses menggunakan layanan Windows NT (aspnet_state.exe) atau tabel SQL Server untuk menyimpan nilai sesi. Oleh karena itu, status sesi tetap berada di luar proses pekerja ASP.NET, dan lapisan kode tambahan diperlukan untuk membuat serialisasi dan deserialisasi antara status sesi dan media penyimpanan sebenarnya. Hal ini terjadi setiap kali permintaan diproses dan kemudian harus dioptimalkan hingga tingkat tertinggi.
Karena data sesi perlu disalin dari repositori eksternal ke kamus sesi lokal, permintaan tersebut mengakibatkan penurunan kinerja mulai dari 15% (di luar proses) hingga 25% (SQL Server). Perlu diingat bahwa meskipun ini hanya perkiraan kasar, namun harus mendekati dampak minimum, dan dampak maksimum akan jauh lebih tinggi dari perkiraan tersebut. Faktanya, perkiraan ini tidak sepenuhnya memperhitungkan kompleksitas tipe yang sebenarnya disimpan dalam status sesi.
Dalam skenario penyimpanan di luar proses, status sesi bertahan lebih lama, membuat aplikasi lebih kuat karena melindungi terhadap kegagalan Microsoft® Internet Information Services (IIS) dan ASP.NET. Dengan memisahkan status sesi dari aplikasi, Anda juga dapat dengan lebih mudah memperluas aplikasi yang ada ke dalam arsitektur Web Farm dan Web Garden. Selain itu, status sesi disimpan dalam proses eksternal, yang pada dasarnya menghilangkan risiko kehilangan data berkala karena perulangan proses.
Berikut cara menggunakan layanan Windows NT. Seperti disebutkan di atas, layanan NT adalah proses bernama aspnet_state.exe, biasanya terletak di folder C:WINNTMicrosoft.NETFrameworkv1.1.4322.
Direktori sebenarnya bergantung pada versi Microsoft® .NET Framework yang sebenarnya Anda jalankan. Sebelum menggunakan server negara, Anda harus memastikan bahwa layanan sudah siap dan berjalan di komputer lokal atau jarak jauh yang digunakan sebagai perangkat penyimpanan sesi. Layanan negara adalah bagian dari dan diinstal dengan ASP.NET, jadi Anda tidak perlu menjalankan penginstal tambahan. Secara default, layanan status tidak berjalan dan perlu dimulai secara manual. Aplikasi ASP.NET akan mencoba membuat sambungan ke server negara segera setelah dimuat. Oleh karena itu, layanan harus siap dan berjalan, jika tidak, pengecualian HTTP akan dilempar. Gambar berikut menunjukkan kotak dialog properti untuk layanan tersebut.
Gambar 2: Kotak dialog Properti Server Negara ASP.NET
Aplikasi ASP.NET perlu menentukan alamat TCP/IP komputer tempat layanan keadaan sesi berada. Pengaturan berikut harus dimasukkan ke dalam file web.config aplikasi.
<konfigurasi>;
<sistem.web>;
<sessionState
mode="Server Negara"
stateConnectionString="tcpip=expoware:42424" />;
</system.web>;
</configuration>;
Atribut stateConnectionString berisi alamat IP komputer dan port yang digunakan untuk pertukaran data. Alamat komputer default adalah 127.0.0.1 (localhost) dan port default adalah 42424. Anda juga dapat menunjukkan komputer berdasarkan namanya. Menggunakan komputer lokal atau jarak jauh sepenuhnya transparan terhadap kode. Perhatikan bahwa karakter non-ASCII tidak dapat digunakan dalam nama, dan nomor port wajib diisi.
Jika Anda menggunakan penyimpanan sesi di luar proses, status sesi akan tetap ada dan tersedia untuk penggunaan di masa mendatang, apa pun yang terjadi pada proses pekerja ASP.NET. Jika layanan terganggu, data akan disimpan dan diambil secara otomatis saat layanan dipulihkan. Namun jika layanan penyedia status berhenti atau gagal, data akan hilang. Jika Anda ingin aplikasi Anda kuat, gunakan mode SQLServer, bukan mode StateServer.
<konfigurasi>;
<sistem.web>;
<sessionState
mode = "SQLServer"
sqlConnectionString="server=127.0.0.1;uid=<id pengguna>;;pwd=<kata sandi>;;" />;
</system.web>;
</configuration>;
Anda dapat menentukan string koneksi melalui atribut sqlConnectionString. Perhatikan bahwa string atribut harus berisi ID pengguna, kata sandi, dan nama server. Itu tidak boleh berisi tag seperti Database dan Katalog Awal karena informasi ini defaultnya adalah nama tetap. ID pengguna dan kata sandi dapat diganti dengan pengaturan keamanan terintegrasi.
Bagaimana cara membuat database? ASP.NET menyediakan dua pasang skrip untuk mengkonfigurasi lingkungan database. Pasangan skrip pertama diberi nama InstallSqlState.sql dan UninstallSqlState.sql dan terletak di folder yang sama dengan layanan Session State NT. Mereka membuat database bernama ASPState dan beberapa prosedur tersimpan. Namun, data disimpan di tempat penyimpanan sementara database TempDB SQL Server. Artinya jika komputer SQL Server di-restart, data sesi akan hilang.
Untuk mengatasi keterbatasan ini, gunakan skrip kedua. Pasangan skrip kedua diberi nama InstallPersistSqlState.sql dan UninstallPersistSqlState.sql. Dalam hal ini, database ASPState dibuat, tetapi tabel dibuat dalam database yang sama dan juga bersifat persisten. Saat Anda menginstal dukungan SQL Server untuk sesi, pekerjaan juga dibuat untuk menghapus sesi yang kedaluwarsa di database status sesi. Pekerjaan tersebut diberi nama ASPState_Job_DeleteExpiredSessions dan selalu berjalan. Harap dicatat bahwa agar pekerjaan ini berfungsi dengan baik, layanan SQLServerAgent harus berjalan.
Apa pun mode yang Anda pilih, cara operasi status sesi dikodekan tidak berubah. Anda selalu dapat mengerjakan properti Session dan membaca serta menulis nilai seperti biasa. Semua perbedaan perilaku ditangani pada tingkat abstraksi yang lebih rendah. Serialisasi status mungkin merupakan perbedaan paling penting antara mode sesi.
Serialisasi dan Deserialisasi Status
Saat menggunakan mode dalam proses, objek disimpan dalam status sesi sebagai instance aktif dari kelasnya masing-masing. Jika tidak terjadi serialisasi dan deserialisasi nyata, berarti Anda sebenarnya dapat menyimpan objek apa pun yang Anda buat di Sesi (termasuk objek yang tidak dapat diserialisasi dan objek COM), dan mengaksesnya tidak akan terlalu mahal. Jika Anda memilih penyedia negara yang tidak sedang diproses, lain ceritanya.
Dalam arsitektur di luar proses, nilai sesi disalin dari media penyimpanan lokal (database AppDomain eksternal) ke memori AppDomain yang menangani permintaan tersebut. Lapisan serialisasi/deserialisasi diperlukan untuk menyelesaikan tugas ini dan mewakili salah satu biaya utama penyedia status di luar proses. Dampak utama situasi ini terhadap kode Anda adalah hanya objek serial yang dapat disimpan dalam kamus sesi.
ASP.NET menggunakan dua metode untuk membuat serialisasi dan deserialisasi data, bergantung pada tipe data yang terlibat. Untuk tipe dasar, ASP.NET menggunakan serializer internal yang dioptimalkan; untuk tipe lain, termasuk objek dan kelas yang ditentukan pengguna, ASP.NET menggunakan formatter biner .NET. Tipe dasar mencakup string, waktu tanggal, nilai Boolean, byte, karakter, dan semua tipe numerik. Untuk jenis ini, menggunakan serializer yang dibuat khusus lebih cepat daripada menggunakan formatter biner .NET umum default.
Serializer yang dioptimalkan tidak dirilis atau didokumentasikan secara publik. Ini hanyalah pembaca/penulis biner dan menggunakan arsitektur penyimpanan yang sederhana namun efektif. Serializer menggunakan kelas BinaryWriter untuk menulis representasi byte dari tipe tersebut, dan kemudian menulis representasi byte dari nilai yang sesuai dengan tipe tersebut. Saat membaca byte berseri, kelas pertama-tama mengekstrak satu byte, mendeteksi tipe data yang akan dibaca, dan kemudian memanggil metode Readxxx tipe spesifik pada kelas BinaryReader.
Perhatikan bahwa ukuran tipe boolean dan numerik sudah diketahui dengan baik, tetapi tidak untuk string. Pada aliran data yang mendasarinya, string selalu diawali dengan panjang tetap (kode bilangan bulat 7-bit yang ditulis sekaligus), dan pembaca menggunakan fakta ini untuk menentukan ukuran string yang benar. Nilai tanggal disimpan dengan menuliskan jumlah total token yang membentuk tanggal saja. Oleh karena itu, untuk membuat serial sesi, tanggalnya harus bertipe Int64.
Anda dapat menggunakan kelas BinaryFormatter untuk melakukan operasi serialisasi pada objek yang lebih kompleks (serta objek khusus) selama kelas yang memuatnya ditandai sebagai dapat serial. Semua tipe non-dasar diidentifikasi oleh ID tipe yang sama dan disimpan dalam aliran data yang sama dengan tipe dasar. Secara keseluruhan, operasi serialisasi dapat mengakibatkan penurunan kinerja sebesar 15% hingga 25%. Namun perlu diperhatikan bahwa ini adalah perkiraan kasar berdasarkan asumsi bahwa tipe dasar digunakan. Semakin kompleks jenis yang digunakan, semakin besar biaya overhead.
Penyimpanan data sesi yang efisien sulit diterapkan tanpa penggunaan tipe primitif secara ekstensif. Jadi, setidaknya secara teori, menggunakan tiga slot sesi untuk menyimpan tiga properti string berbeda dari suatu objek lebih baik daripada membuat serial seluruh objek. Namun bagaimana jika objek yang ingin Anda serialkan berisi 100 properti? Mau pakai 100 slot atau 1 slot saja? Dalam banyak kasus, pendekatan yang lebih baik adalah dengan mengubah tipe kompleks menjadi beberapa tipe yang lebih sederhana. Pendekatan ini didasarkan pada tipe konverter. Sebuah "konverter tipe" adalah serializer ringan yang mengembalikan properti kunci suatu tipe sebagai kumpulan string. Pengonversi tipe adalah kelas eksternal yang terikat ke kelas dasar menggunakan atribut. Terserah kepada penulis ketik untuk memutuskan properti mana yang disimpan dan bagaimana caranya. Konverter tipe juga berguna untuk penyimpanan ViewState dan mewakili metode penyimpanan sesi yang lebih efisien dibandingkan pemformat biner.
Siklus Hidup Sesi
Poin penting tentang manajemen sesi ASP.NET adalah bahwa siklus hidup objek keadaan sesi dimulai hanya ketika item pertama ditambahkan ke kamus dalam memori. Sesi ASP.NET dianggap dimulai hanya setelah cuplikan kode berikut dijalankan.
Session["MySlot"] = "Beberapa data";
Kamus Sesi biasanya berisi tipe Objek. Untuk membaca data mundur, nilai yang dikembalikan perlu dikonversi ke tipe yang lebih spesifik.
string data = (string) Session["MySlot"];
Ketika halaman menyimpan data ke Sesi, nilainya akan dimuat ke dalam kelas kamus yang dibuat khusus yang terdapat dalam kelas HttpSessionState. Isi kamus dimuat ke penyedia negara ketika permintaan yang sedang diproses selesai. Jika status sesi kosong karena data tidak dimasukkan ke dalam kamus secara terprogram, data tidak akan diserialkan ke media penyimpanan dan, yang lebih penting, tidak akan disajikan di ASP.NET Cache, SQL Server, atau NT State Services Create slot untuk melacak sesi saat ini. Hal ini karena alasan kinerja, namun memiliki dampak penting pada cara ID sesi ditangani: ID sesi baru akan dibuat untuk setiap permintaan hingga beberapa data disimpan dalam kamus sesi.
Ketika perlu untuk menghubungkan status sesi dengan permintaan yang sedang diproses, modul HTTP mengambil ID sesi (jika ini bukan permintaan awal) dan mencarinya di penyedia status yang dikonfigurasi. Jika tidak ada data yang dikembalikan, modul HTTP menghasilkan ID sesi baru untuk permintaan tersebut. Hal ini dapat dengan mudah diuji dengan halaman berikut:
<%@ Page Language="C#" Trace="true" %>;
</html>;
<tubuh>;
<form runat="server">;
<asp:button runat="server" text="Klik" />;
</bentuk>;
</badan>;
</html>;
Setiap kali Anda mengklik tombol dan kembali ke halaman, ID sesi baru akan dibuat dan informasi pelacakan akan dicatat.
Gambar 3: Dalam aplikasi yang tidak menyimpan data dalam kamus sesi, ID sesi baru dibuat untuk setiap permintaan.
Bagaimana dengan acara Session_OnStart? Akankah acara tersebut dimunculkan untuk setiap permintaan juga? Jika aplikasi Anda mendefinisikan pengendali Session_OnStart, status sesi selalu disimpan, meskipun status sesi kosong. Oleh karena itu, ID sesi selalu konstan untuk semua permintaan setelah permintaan pertama. Gunakan pengendali Session_OnStart hanya jika benar-benar diperlukan.
Jika waktu sesi habis atau ditinggalkan, ID sesinya tidak berubah saat aplikasi tanpa status diakses lagi. Ini dirancang agar ID sesi tetap ada hingga akhir sesi browser, meskipun status sesi telah berakhir. Artinya, ID sesi yang sama selalu digunakan untuk mewakili beberapa sesi selama instance browsernya sama.
Acara Session_OnEnd menandai akhir sesi dan digunakan untuk mengeksekusi kode pembersihan apa pun yang diperlukan untuk mengakhiri sesi. Namun perlu diperhatikan bahwa peristiwa ini hanya didukung dalam mode InProc, yaitu hanya ketika data sesi disimpan dalam proses pekerja ASP.NET. Agar peristiwa Session_OnEnd dapat dimunculkan, status sesi harus ada terlebih dahulu, artinya beberapa data harus disimpan dalam status sesi, dan setidaknya satu permintaan harus diselesaikan.
Dalam mode InProc, status sesi ditambahkan ke cache saat item diberi kebijakan waktu kedaluwarsa variabel. Kedaluwarsa variabel artinya jika suatu barang tidak digunakan dalam jangka waktu tertentu maka akan dihapus. Waktu kedaluwarsa setiap permintaan yang diproses selama periode ini akan diatur ulang. Interval item status sesi diatur ke batas waktu sesi. Teknik yang digunakan untuk mereset waktu berakhirnya status sesi sangat sederhana dan intuitif: modul HTTP sesi hanya membaca item status sesi yang disimpan di ASP.NET Cache. Jika struktur internal objek ASP.NET Cache diketahui, modul akan melakukan perhitungan untuk mengatur ulang waktu kedaluwarsa variabel. Jadi ketika item yang di-cache habis masa berlakunya, waktu sesi telah habis.
Item yang kadaluwarsa akan otomatis dihapus dari cache. Modul sesi status juga mewakili fungsi panggilan balik penghapusan sebagai bagian dari kebijakan waktu kedaluwarsa untuk proyek ini. Cache secara otomatis akan memanggil fungsi delete, yang kemudian akan memunculkan event Session_OnEnd. Jika aplikasi melakukan manajemen sesi melalui komponen di luar proses, kejadian akhir tidak akan pernah dimunculkan.
Sesi Tanpa Cookie
Setiap sesi ASP.NET yang aktif diidentifikasi menggunakan string 120-bit yang hanya terdiri dari karakter yang diizinkan oleh URL. ID sesi dihasilkan menggunakan penyedia kriptografi pembuat nomor acak (RNG). Penyedia layanan mengembalikan urutan 15 angka yang dihasilkan secara acak (15 byte x 8 bit = 120 bit). Array angka acak kemudian dipetakan ke karakter URL yang valid dan dikembalikan sebagai string.
String ID sesi dikirim ke browser dan dikembalikan ke aplikasi server dengan salah satu dari dua cara: menggunakan cookie (seperti di ASP tradisional) atau URL yang dimodifikasi. Secara default, modul status sesi akan membuat cookie HTTP di sisi klien, namun URL yang dimodifikasi yang menyematkan string ID sesi dapat digunakan (terutama untuk browser yang tidak mendukung cookie). Metode mana yang digunakan bergantung pada pengaturan konfigurasi yang disimpan dalam file web.config aplikasi. Untuk mengonfigurasi pengaturan sesi, Anda dapat menggunakan bagian <sessionState> dan atribut Cookieless.
<sessionState cookieless="true|false" />;
Secara default, atribut Cookieless adalah false, yang menunjukkan bahwa cookie digunakan. Faktanya, cookie hanyalah file teks yang ditempatkan pada hard drive klien oleh halaman Web. Di ASP.NET, cookie diwakili oleh turunan kelas HttpCookie. Biasanya, cookie berisi nama, sekumpulan nilai, dan waktu kedaluwarsa. Ketika atribut Cookieless disetel ke false, modul status sesi akan benar-benar membuat cookie bernama ASP.NET_SessionId dan menyimpan ID sesi di dalamnya. Pseudocode berikut menunjukkan proses pembuatan cookie:
HttpCookie sessionCookie;
sessionCookie = HttpCookie baru("ASP.NET_SessionId", sessionID);
sessionCookie.Path = "/";
Waktu kedaluwarsa sesi Cookie sangat singkat, dan waktu kedaluwarsa diperbarui setelah setiap permintaan berhasil. Atribut Expires pada cookie menunjukkan waktu kedaluwarsa cookie pada klien. Jika cookie sesi tidak disetel secara eksplisit, properti Kedaluwarsa ditetapkan secara default ke DateTime.MinValue, yang merupakan unit waktu terkecil yang diizinkan oleh .NET Framework.
Untuk menonaktifkan cookie sesi, atur atribut Cookieless ke true dalam file konfigurasi sebagai berikut:
<configuration>;
<sistem.web>;
<sessionState Cookieless="benar" />;
</system.web>;
</configuration>;
Pada titik ini, asumsikan Anda meminta halaman di URL berikut:
http://www.contoso.com/sample.aspxKonten
sebenarnya yang ditampilkan di bilah alamat browser akan berbeda dan sekarang berisi ID sesi , sebagai berikut Ditampilkan di:
http://www.contoso.com/(5ylg0455mrvws1uz5mmaau45)/sample.aspx
Saat membuat instance modul HTTP status sesi, modul memeriksa nilai atribut Cookieless. Jika benar, alihkan permintaan (HTTP 302) ke URL virtual yang dimodifikasi yang berisi ID sesi tepat sebelum nama halaman. Saat permintaan diproses kembali, ID sesi akan disertakan dalam permintaan. Jika permintaan dibuat untuk memulai sesi baru, modul HTTP menghasilkan ID sesi baru dan kemudian mengalihkan permintaan tersebut. Jika permintaan diposkan kembali, ID sesi sudah ada karena pos balik menggunakan URL relatif.
Kerugian menggunakan sesi tanpa cookie adalah status sesi hilang jika URL absolut dipanggil. Saat menggunakan cookie, Anda dapat menghapus bilah alamat, membuka aplikasi lain, lalu kembali ke aplikasi sebelumnya dan mengambil nilai sesi yang sama. Jika Anda melakukan ini saat cookie sesi dinonaktifkan, data sesi akan hilang. Misalnya, kode berikut akan mengganggu sesi:
<a runat="server" href="/code/page.aspx">;
Klik</a>;
secara manual mengubah ID sesi yang ditambahkan ke URL. Anda dapat memanggil metode ApplyAppPathModifier di kelas HttpResponse.
<a runat="server"
href=<% =Response.ApplyAppPathModifier("/code/page.aspx")%>; >;Click</a>;
Metode ApplyAppPathModifier akan menggunakan string yang mewakili URL dan mengembalikan URL absolut yang menyematkan informasi sesi. Teknik ini sangat berguna ketika, misalnya, Anda perlu mengalihkan dari halaman HTTP ke halaman HTTPS.
Status SesiRingkasan
awalnya diperkenalkan dengan ASP tradisional sebagai API berbasis kamus yang memungkinkan pengembang menyimpan data khusus selama sesi. Di ASP.NET, status sesi mendukung dua fitur utama: penyimpanan dan transfer ID sesi tanpa cookie, dan penyedia status tempat data sesi sebenarnya disimpan. Untuk mengimplementasikan dua kemampuan baru ini, ASP.NET memanfaatkan modul HTTP untuk mengontrol pengikatan antara status sesi dan konteks permintaan yang sedang diproses.
Dalam ASP tradisional, menggunakan status sesi berarti menggunakan cookie. Hal ini tidak lagi terjadi di ASP.NET, karena arsitektur tanpa cookie dapat digunakan. Dengan kekuatan modul HTTP, URL yang diminta dapat didekomposisi sehingga berisi ID sesi dan kemudian dialihkan. Selanjutnya, modul HTTP mengekstrak ID sesi dari URL dan menggunakannya untuk mengambil status tersimpan.
Keadaan fisik suatu sesi dapat disimpan di tiga lokasi: memori dalam proses, memori di luar proses, dan tabel SQL Server. Data harus diserialisasi/deserialisasi sebelum dapat digunakan oleh aplikasi. Modul HTTP menyalin nilai sesi dari penyedia ke dalam memori aplikasi pada awal permintaan. Setelah permintaan selesai, status yang diubah dikembalikan ke penyedia. Komunikasi data ini akan memiliki berbagai tingkat efek samping pada kinerja, tetapi akan sangat meningkatkan keandalan dan stabilitas dan membuat dukungan untuk arsitektur Web Farm dan Web Garden lebih mudah diimplementasikan.