ניהול מתקדם של sessions

‏ • 10 בפברואר, 2003



המאמר מיועד לאנשים בעלי ידע בינוני בשפת ASP.

אם יש לכם אתר גדול או שאתם מתכננים לבנות אתר גדול הכולל מערכת מורכבת של משתמשים, פורום, חנות או דברים כאלה, אתם בוודאי רוצים לדעת מי מחובר, באיזה עמוד הוא נמצא וכמה זמן הוא כבר מחובר.
כיום, יש הרבה שיטות ושירותים שמציעים אתרים אחרים, אבל אני רוצה כאן להסביר על שיטה ממש טובה (לדעתי) שהמצאתי לניהול מתקדם של משתמשים מחוברים.

ידוע שבשפת ASP, כשמשתמש נכנס לאתר נפתח בשרת session שמיוחד לו. אפשר כמובן להשתמש במשתני sessions כדי לשמור את דרגת המשתמש או עוד פרטים עליו, אבל זאת דרך ממש לא יעילה כי כל משתנה session תופס בקירוב 100kb. אז מה יקרא עם השרת כשיהיו באתר 100 משתמשים כשלכול אחד 7 משתני session ? או שהשרת יקרוס מחוסר זיכרון, או שהאתר יעבוד ממש ממש לאט. בנוסף לזה, כשמשתמשים במשתני sessions אין אפשרות לראות את תוכן המשתנים של כל המשתמשים, אלא רק את שלך. אז מה אפשר לעשות?

קודם נגדיר את המסד נתונים:
1. פתח מסד נתונים חדש מסוג access.
2. הוסף טבלה בשם sessions דרך design mode.
3. קבע את השדות בטבלה לפי האופן הבא:


השדה: sessionID

השדה: IP

השדה: name

השדה: userID

השדה: page

השדה: last_request

עכשיו, אחרי שבנינו את הטבלה נבנה את הדף הראשון ואחרי זה נסביר אותו.
הדף מסתמך על זה שלפני קטע הקוד הכתוב למטה, יש חיבור למסד הנתונים שבנינו לפני זה באובייקט שנקרא conn.

אלגוריתם:
1. נמחק את הרשומות מהטבלה: sessions בהם זמן הפעולה האחרונה הוא יותר מ- 20 דקות.
2. נבדוק אם המשתמש כבר רשום בטבלה על ידי חיפוש ה sessionID של המשתמש בטבלה.
3. אם המשתמש קיים אז:
3.1 עדכן את העמוד הנוכחי בו נמצא המשתמש.
3.2 עדכן את זמן הפעולה האחרונה של המשתמש.
4. אם המשתמש לא קיים אז:
4.1 הוסף רשומה לטבלה עם הפרטים הבאים:
4.1.1 הכנס את ה sessionID של המשתמש לשדה: sessionID.
4.1.2 הכנס את כתובת האייפי של המשתמש לשדה: IP.
4.1.3 הכנס את הכתובת בו נמצא המשתמש לשדה: page.
4.1.4 הכנס לשדה: name את המילה: "אורח".
4.1.5 הכנס לשדה: userID את המספר 0.
4.1.6 הכנס לשדה: last_request את הזמן העכשווי.
5. סגור את חיבור ה recordset.
6. שחרר את הזיכרון שניתן לאובייקט.

עכשיו בואו נממש את האלגוריתם:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25  

<%
    conn.execute "delete * from sessions where last_request < Now()-0.015"
    set rsses=server.createobject("ADODB.recordset")
    rsses.open "select * from sessions where sessionID="& session.sessionID, conn, 1, 2

    if rsses.eof then
         rsses.close
         rsses.open "sessions", conn, 2, 3, 2
         rsses.addnew
              rsses("sessionID")=session.sessionID
              rsses("IP")=request.servervariables("REMOTE_ADDR")
              rsses("page")=request.servervariables("URL")
              rsses("name")="אורח"
              rsses("userID")=0
              rsses("last_request")=Now()
         rsses.update
    else
         rsses("page")=request.servervariables("URL")
         rsses("last_request")=Now()
         rsses.update
    end if
    rsses.close
    set rsses=nothing
%>


הדף הזה צריך להיות ממוקם בכול עמוד באתר, כי הוא אחראי על ניהול המשתמשים.
עכשיו, נבנה דף ניהול שיטפל בכל ה sessions הפתוחים, כולל עידכון שדות ומחיקת רשומות (מה שלא מתאפשר בשימוש עם משתני sessions).
הדף הראשון (admin.asp) הוא הדף שיוצג למנהל ותוכן הדף הוא:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34  

<!– #Include File = sessions.asp –> ' הכללת הקובץ שכתבנו קודם.

<%
response.write "<html dir=rtl><head><title>ניהול sessions</title></head><body>"
set rsses=server.createobject("ADODB.recordset")
rsses.open "select * from sessions", conn, 1, 2

response.write "מספר המשתמשים באתר: "& rsses.recordcount &"<br><br>"
response.write "<table align=center border=1 bordercolor=#000000 style='border-collapse: collapse' cellpadding=5 width='100%'>"
response.write "<tr align=center><th colspan=2>ניהול</th><th>מספר session</th><th>מספר משתמש</th>"
response.write "<th>שם המשתמש</th><th>מספר IP</th><th>דף נוכחי</th><th>פעולה אחרונה</th></tr>"

    while not rsadmin.eof
        response.write "<form method=post action=admin2.asp?mode=edit>"
        response.write "<input type=hidden name=sessionID value="& rsses("sessionID") &">"
        response.write "<tr align=center>"
        response.write "<td><div onclick='submit();'>עדכן</div></td>"
        response.write "<td><div onclick='admin2.asp?mode=delete&ID="& rsses("sessionID") &"'>מחק</div></td>"
        response.write "<td>"& rsses("sessionID") &"</td>"
        response.write "<td>"& rsadmin("userID") &"</td>"
        response.write "<td><input type=text name=username value='"& rsses("name") &"' size=20></td>"
        response.write "<td>"& rsses("IP") &"</td>"
        response.write "<td><div dir='ltr'>"& rsses("page") &"</div></td>"
        response.write "<td>"& rsses("last_request") &"</td>"
        response.write "</tr>"
        response.write "</form>"
        rsses.movenext
    wend

response.write "</table>"
rsses.close
set rsses=nothing
response.write "</font></body></html>"
%>


כפי ששמתם לב, דף זה קורא לדף: admin2.asp בכדי לעדכן ולמחוק רשומות (משתמשים).
תוכן הדף השני (admin2.asp) הוא:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18  

<%
if request.querystring("mode")="edit" then
     set rsses=server.createobject("ADODB.recordset")
     rsses.open "select * from sessions where sessionID="& request.form("sessionID"), conn, 1, 2
     rsses("name")=request.form("username")
     rsses.update
     rsses.close
     set rsses=nothing
else
     if request.querystring("mode")="delete" then
          if request.querystring("ID")<>"" then
               conn.execute "delete * from sessions where sessionID="& request.querystring("ID")
          end if
     end if
end if
response.redirect "admin.asp"
%>


למעשה זהו…
מי שקרא טוב את הקוד בטוח הבין איך השיטה פועלת, אבל אם עדיין יש שאלות אז תשלחו לי אימייל עם הנושא: "בקשר למאמר מספר 1"

בברכה, אלכסנדר סירוטין, מתכנת מערכות…



תגיות: ,

תגובות בפייסבוק