ทำความเข้าใจกับสถานะเซสชันของ asp.net
ผู้เขียน:Eve Cole
เวลาอัปเดต:2009-07-01 16:44:49
1. ฟังก์ชั่นสถานะเซสชัน
HTTP เป็นโปรโตคอลไร้สถานะ ดังนั้นจึงไม่ได้ระบุโดยอัตโนมัติว่าลำดับคำขอทั้งหมดมาจากไคลเอ็นต์เดียวกัน หรือแม้แต่เบราว์เซอร์ตัวเดียวยังคงดูหน้าเว็บหรือไซต์อยู่หรือไม่ และเราสามารถใช้ฟังก์ชันสถานะเซสชันในตัวของ ASP.net ได้
1. ระบุและจัดประเภทคำขอโดยอัตโนมัติจากไคลเอ็นต์เบราว์เซอร์เดียวไปยังเซสชันแอปพลิเคชันแบบลอจิคัลบนเซิร์ฟเวอร์
2. จัดเก็บข้อมูลที่กำหนดขอบเขตเซสชันไว้บนเซิร์ฟเวอร์เพื่อใช้กับคำขอเบราว์เซอร์หลายรายการ
3. เพิ่มเหตุการณ์การจัดการอายุการใช้งานเซสชันที่เหมาะสม (Session_OnStart, Session_OnEnd ฯลฯ) ที่สามารถจัดการได้ในรหัสแอปพลิเคชัน
2. การระบุสถานะเซสชัน
เมื่อสร้างเซสชัน เซิร์ฟเวอร์จะสร้าง ID แยกกันสำหรับแต่ละเซสชัน ตัวระบุจะแสดงด้วยสตริง SessionID 120 บิตที่มีเฉพาะอักขระ ASCII ที่อนุญาตใน URL ค่า SessionID ถูกสร้างขึ้นโดยใช้อัลกอริทึมที่รับประกันความเป็นเอกลักษณ์และการสุ่ม วัตถุประสงค์ของการรับประกันความเป็นเอกลักษณ์คือเพื่อให้แน่ใจว่าเซสชันจะไม่ขัดแย้งกัน และจุดประสงค์ในการรับประกันการสุ่มคือเพื่อให้แน่ใจว่าผู้ใช้ที่เป็นอันตรายจะไม่สามารถใช้ SessionID ใหม่เพื่อคำนวณจำนวนที่มีอยู่ เซสชัน SessionID
3. วิธีจัดเก็บสถานะเซสชัน
มีสามวิธีในการจัดเก็บสถานะเซสชัน:
1. โหมดสถานะเซสชันที่กำลังดำเนินการ (Inproc): เมื่อเราสร้างโปรแกรมเว็บใหม่ โหมดสถานะเซสชันที่กำลังดำเนินการจะถูกนำมาใช้เป็นค่าเริ่มต้น นี่เป็นโหมดที่ทุกคนใช้กันทั่วไปเช่นกัน ในโหมดนี้ สถานะเซสชันจะถูกจัดเก็บไว้ในกระบวนการของผู้ปฏิบัติงาน ASP.NET ดังนั้นโหมดสถานะเซสชันที่อยู่ระหว่างดำเนินการจึงน่าจะเป็นตัวเลือกการเข้าถึงที่เร็วที่สุด แต่ยิ่งมีข้อมูลเก็บไว้ในเซสชันมากเท่าใด เว็บเซิร์ฟเวอร์ก็จะยิ่งใช้หน่วยความจำมากขึ้น ซึ่งอาจเพิ่มความเสี่ยงที่ประสิทธิภาพจะลดลง
2. โหมดเซิร์ฟเวอร์สถานะ .NET (StateServer): สถานะเซสชันถูกจัดเก็บไว้ในกระบวนการระยะไกล (ตัวอย่างเช่น ในบริการ windows NT ชื่อ aspnet_state.exe)
3. โหมด SQL (SQLServer): สถานะเซสชันถูกจัดเก็บไว้ในตารางฐานข้อมูลเฉพาะที่จัดการโดย SQL Server
ทั้งโหมดเซิร์ฟเวอร์สถานะ .NET และโหมด SQL สามารถเรียกว่าโหมดเซสชันที่ไม่อยู่ในกระบวนการได้ เมื่อจัดเก็บข้อมูล ข้อมูลจะต้องมีการซีเรียลไลซ์และจัดเก็บไว้ในพื้นที่เก็บข้อมูลภายนอก เมื่ออ่านและข้อมูล จะต้องทำการดีซีเรียลไลซ์และคัดลอกข้อมูล ไปยังพจนานุกรมเซสชันในเครื่อง ดังนั้นคำขอส่งผลให้ประสิทธิภาพลดลง 15% (ไม่อยู่ในกระบวนการ) ถึง 25% (SQL Server) โปรดทราบว่านี่เป็นเพียงการประมาณการคร่าวๆ เท่านั้น แต่ในสถานการณ์การจัดเก็บข้อมูลนอกกระบวนการ สถานะเซสชันจะอยู่ได้นานกว่า ทำให้แอปพลิเคชันมีประสิทธิภาพมากขึ้น เนื่องจากป้องกัน Microsoft® Internet Information Services (IIS) และความล้มเหลวของ ASP.NET ด้วยการแยกสถานะเซสชันออกจากแอปพลิเคชัน คุณสามารถขยายแอปพลิเคชันที่มีอยู่ไปยังสถาปัตยกรรม Web Farm และ Web Garden ได้ง่ายขึ้น นอกจากนี้ สถานะเซสชันจะถูกจัดเก็บไว้ในกระบวนการภายนอก ซึ่งช่วยลดความเสี่ยงที่ข้อมูลจะสูญหายเป็นระยะเนื่องจากการวนซ้ำของกระบวนการ
4. การกำหนดค่าสถานะเซสชัน
การกำหนดค่าสถานะเซสชันทำได้โดยการตั้งค่าส่วน <sessionState> ของไฟล์ Web.config ต่อไปนี้จะแนะนำวิธีการกำหนดค่าเฉพาะของสถานะเซสชันทั้งสาม
1. โหมดระหว่างดำเนินการ
โหมดระหว่างดำเนินการเป็นโหมดสถานะเซสชันเริ่มต้น หากต้องการใช้โหมดในกระบวนการ ให้ตั้งค่าแอตทริบิวต์โหมดขององค์ประกอบ <sessionState> เป็น Inproc
ตัวอย่างการตั้งค่าสำหรับโหมดในกระบวนการแสดงอยู่ด้านล่าง http://www.downcodes.com
<การกำหนดค่า>
<system.เว็บ>
<โหมด sessionState = "ไม่ถูกต้อง"
ไร้คุกกี้ = "เท็จ"
หมดเวลา = "20"/>
</sessionState>
</system.web>
</การกำหนดค่า>
2. โหมดเซิร์ฟเวอร์สถานะ
เมื่อต้องการใช้เซิร์ฟเวอร์สถานะ คุณต้องตรวจสอบให้แน่ใจก่อนว่าบริการสถานะ ASP.NET ทำงานบนเซิร์ฟเวอร์ระยะไกลที่ใช้สำหรับการจัดเก็บเซสชัน บริการนี้ได้รับการติดตั้งด้วย ASP.NET และ Visual Studio .NET ที่:
systemrootMicrosoft.NETFrameworkversionNumberaspnet_state.exe
จากนั้น ในไฟล์ Web.config ของแอปพลิเคชัน ให้ตั้งค่าแอตทริบิวต์โหมดขององค์ประกอบ <sessionState> เป็น StateServer สุดท้าย ให้ตั้งค่าคุณสมบัติ ConnectionString เป็น tcpip=serverName:portNumber
ต่อไปนี้เป็นตัวอย่างการตั้งค่าสำหรับโหมดเซิร์ฟเวอร์สถานะ
<การกำหนดค่า>
<system.เว็บ>
<โหมดเซสชันสถานะ = "เซิร์ฟเวอร์สถานะ"
stateConnectionString="tcpip=เซิร์ฟเวอร์ข้อมูล:42424"
ไร้คุกกี้ = "เท็จ"
หมดเวลา = "20"/>
</sessionState>
</system.web>
3. โหมดเซิร์ฟเวอร์ SQL
หากต้องการใช้ SQL Server ให้รัน InstallSqlState.sql หรือ InstallPersistSqlState.sql บนคอมพิวเตอร์ SQL Server ก่อน ซึ่งสถานะเซสชันจะถูกจัดเก็บ สคริปต์ทั้งสองสร้างฐานข้อมูลชื่อ ASPState ซึ่งมีกระบวนงานที่เก็บไว้หลายขั้นตอน
ความแตกต่างระหว่างสคริปต์ทั้งสองคือตำแหน่งที่ตาราง ASPStateTempApplications และ ASPStateTempSessions ถูกวางไว้ สคริปต์ InstallSqlState.sql เพิ่มตารางเหล่านี้ลงในฐานข้อมูล TempDB ซึ่งจะสูญเสียข้อมูลเมื่อรีสตาร์ทคอมพิวเตอร์ สคริปต์ InstallPersistSqlState.sql จะเพิ่มตารางเหล่านี้ลงในฐานข้อมูล ASPState แทน ซึ่งอนุญาตให้เก็บข้อมูลเซสชันไว้ระหว่างที่คอมพิวเตอร์รีสตาร์ท
ตามค่าเริ่มต้น ไฟล์สคริปต์ทั้งสองจะถูกติดตั้งในตำแหน่งต่อไปนี้:
systemrootMicrosoft.NETFrameworkversionNumber
จากนั้น ในไฟล์ Web.config ของแอปพลิเคชัน ให้ตั้งค่าแอตทริบิวต์โหมดขององค์ประกอบ <sessionState> เป็น SQLServer สุดท้าย ให้ตั้งค่าคุณสมบัติ sqlConnectionString เป็น Integrated Security=SSPI;data source=serverName;
ตัวอย่างการตั้งค่าคอนฟิกูเรชันสำหรับโหมด SQL Server แสดงอยู่ด้านล่าง
<การกำหนดค่า>
<system.เว็บ>
<โหมดเซสชันสเตท = "SQLServer"
sqlConnectionString="การรักษาความปลอดภัยแบบรวม=SSPI;แหล่งข้อมูล=เซิร์ฟเวอร์ข้อมูล;"
ไร้คุกกี้ = "เท็จ"
หมดเวลา = "20"/>
</sessionState>
</system.web>
</การกำหนดค่า>
ในโหมด SQL Server สถานะเซสชันสามารถกำหนดค่าให้ทำงานในคลัสเตอร์ล้มเหลวได้ คลัสเตอร์ล้มเหลวคือเว็บเซิร์ฟเวอร์ซ้ำซ้อนที่เหมือนกันตั้งแต่สองตัวขึ้นไปที่เก็บข้อมูลเซสชันในฐานข้อมูล SQL Server บนคอมพิวเตอร์เครื่องอื่น หากเว็บเซิร์ฟเวอร์ตัวหนึ่งล้มเหลว เซิร์ฟเวอร์อื่นในคลัสเตอร์จะเข้ามาทำหน้าที่แทนและให้บริการตามคำขอโดยไม่สูญเสียข้อมูลเซสชัน
ในการกำหนดค่าคลัสเตอร์ล้มเหลว ให้ตั้งค่าองค์ประกอบ <machinekey> ในไฟล์ Web.config ของเว็บเซิร์ฟเวอร์ให้เป็นค่าเดียวกัน
จากนั้นตั้งค่าสตริงการเชื่อมต่อ SQL ของเว็บเซิร์ฟเวอร์ให้ชี้ไปที่ฐานข้อมูล SQL Server บนคอมพิวเตอร์ของคุณที่เก็บข้อมูลเซสชัน
5. การเข้าถึงสถานะเซสชัน
คุณสามารถเข้าถึงสถานะเซสชันได้โดยตรงผ่านคอลเลกชันเซสชัน เพื่อความเข้ากันได้กับ ASP เวอร์ชันก่อนหน้า การเข้าถึงสถานะเซสชันสามารถทำได้ผ่านคุณสมบัติ Session.Contents บนออบเจ็กต์แอปพลิเคชัน
ตัวอย่างต่อไปนี้แสดงการเขียนค่าสองค่าลงในคอลเลกชัน Session บนหน้าเว็บแรก จากนั้นอ่านค่าคอลเลกชัน Session บนหน้าเว็บที่สอง หมายเหตุ: รหัสหน้าจะถูกละเว้นที่นี่
หน้าเว็บแรก เขียนค่าลงในคอลเลกชันเซสชัน
ชื่อสลัวเป็น string = "a"
รหัสสลัวเป็นจำนวนเต็ม = "1"
เซสชั่น("ชื่อ") = ชื่อ
เซสชัน ("id") = id
หน้าเว็บที่สองรับค่าจากคอลเลกชันเซสชัน
ชื่อสลัวเป็น string = session("name")
dim id เป็นจำนวนเต็ม = session("id")
'รับจำนวนรายการในคอลเลกชันสถานะเซสชัน
dim i เป็นจำนวนเต็ม = session.count
โปรดทราบว่าในโหมดในกระบวนการ จะไม่มีการซีเรียลไลซ์และดีซีเรียลไลซ์จริงเกิดขึ้น ดังนั้นอ็อบเจ็กต์จึงถูกจัดเก็บไว้ในสถานะเซสชันเป็นอินสแตนซ์ที่ใช้งานอยู่ของคลาสที่เกี่ยวข้อง
ในโหมดเซสชันนอกกระบวนการ เนื่องจากมีการใช้ซีเรียลไลซ์เซชันและดีซีเรียลไลซ์ คุณจะต้องแปลงชนิดข้อมูลตามสถานการณ์
หากคุณกำลังซีเรียลไลซ์ค่าวันที่ วันที่ควรเป็นประเภท Int64
6. เหตุการณ์การจัดการอายุการใช้งานเซสชัน
มีเหตุการณ์การจัดการอายุการใช้งานเซสชันสองเหตุการณ์ ได้แก่ เหตุการณ์ Session_OnStart และเหตุการณ์ Session_OnEnd คุณสามารถตั้งค่าได้ในไฟล์ Global.asax.VB
1. เหตุการณ์ Session_OnStart
เมื่อไคลเอ็นต์เบราว์เซอร์เดียวเชื่อมต่อกับเซิร์ฟเวอร์ เหตุการณ์ Session_OnStart จะถูกทริกเกอร์ ซึ่งเป็นจุดเริ่มต้นของเซสชัน เหตุการณ์นี้จะไม่ถูกทริกเกอร์อีกต่อไปในระหว่างการเรียกดูครั้งต่อไป เว้นแต่เซสชันจะหมดเวลาหรือถูกละทิ้ง เหตุการณ์ Session_OnStart เป็นเวลาที่ดีที่สุดในการตั้งค่าตัวแปรเซสชันเนื่องจากมีการตั้งค่าก่อนที่จะเข้าถึงเพจใดๆ
ตัวอย่าง: ตัวอย่างต่อไปนี้คือโค้ดเหตุการณ์ Session_OnStart ที่ใช้กันทั่วไปสำหรับการนับจำนวนคนที่ออนไลน์:
Sub Session_Start (ผู้ส่ง ByVal As Object, ByVal e As EventArgs)
'เมื่อมีเหตุการณ์เกิดขึ้น ให้บวก 1 กับจำนวนผู้ใช้ออนไลน์'
แอปพลิเคชัน ("จำนวนผู้ใช้") = แอปพลิเคชัน ("จำนวนผู้ใช้") + 1
จบหมวดย่อย
2. เหตุการณ์ Session_OnEnd
เหตุการณ์ Session_OnEnd เกิดขึ้นเมื่อเซสชันละทิ้งหรือหมดเวลา และถือเป็นจุดสิ้นสุดของเหตุการณ์ แต่โปรดทราบว่ากิจกรรมนี้รองรับในโหมด InProc เท่านั้น คุณสามารถระบุระยะเวลาการหมดเวลาผ่านแอตทริบิวต์การหมดเวลาของส่วน <sessionState> ของไฟล์ Web.config หากผู้ใช้อยู่ภายในระยะเวลาการหมดเวลา (เป็นนาที ค่าเริ่มต้นคือ 20 นาที
นาฬิกา) หากไม่มีการรีเฟรชหรือร้องขอหน้าเว็บ เซสชั่นจะสิ้นสุดลง คุณสามารถใช้เหตุการณ์ Session_OnEnd เพื่อทำการล้างข้อมูลได้
ตัวอย่าง: ตัวอย่างต่อไปนี้คือโค้ดเหตุการณ์ Session_OnEnd ที่ใช้กันทั่วไปสำหรับการนับจำนวนคนที่ออนไลน์:
Sub Session_End (ผู้ส่ง ByVal As Object, ByVal e As EventArgs)
แอปพลิเคชัน ("จำนวนผู้ใช้") = แอปพลิเคชัน ("จำนวนผู้ใช้") - 1
จบหมวดย่อย