〓簡介〓
有點常識的人都知道本身用asp做這種功能顯然有些牽強,因為他不像qq,msn或irc 聊天室那樣是即時通訊,他都是靠刷新網頁更改最後活動時間來獲取用戶是否在線的,所以您不要指望下面這片教程有多完美,我也只是把我的思維模式記錄下來,有啥不對的地方還請高手們多多指教!
-------------------------------------------------- ------------------------------
〓文〓
首先我先向大家介紹一下我實現這個效果的思路,如果你看過我的思路後就能理解完全沒必要將這篇東西看完…
實現這個功能我只能想到兩種方式來實現:
1。資料庫+asp
做起來可能會複雜些,但是適合有大量登陸用戶的系統裡。
2。 application
用application物件:如果你做的是大型社區,你可能要為每個登陸id生成一個appliaction,這樣做雖然程式上設計會簡單些但登陸用戶過多及其耗費伺服器資源,我在這裡決不提倡,因為appliaction物件在使用者登陸時產生很容易但是要做到真正的隨著使用者退出系統完全釋放掉,到目前我還沒看到更好的方法~
因此還是讓我們來看看用資料庫+asp是如何實現同一個帳號不能同時登陸的問題的吧!
首先問用戶建立資料庫這裡我們用access新建一個onlyNet118.mdb
資料表1: users 存放使用者註冊資料
下設資料表:uID(自動編號) userName(字元型) userPass(字元型)
資料表2: onlyLogin 存放使用者臨時登陸訊息
下設資料表: OLname(字元型) OLtime(日期型) OLip(字元型)
資料庫建好後我們直接在users表中手動添加資料userName表添加Net118,userPass表裡添加111,為了能突出我們本文討論的重點,去掉不必要的廢話,所以密碼也不要加密了,用戶名也自己添加~哈哈~
好了,現在資料庫裡面有使用者資料庫,下面我們來做使用者登陸介面,複製下面程式碼存成onlyLogin.asp檔。
<html>
<head>
<meta http-equiv=Content-Type content=text/html; charset=gb2312>
<title>Net118.COM禁止同一帳號不同地區同時登陸</title>
</head>
<body>
<form name=form1 method=post action=loginPost.asp>
使用者名稱:<input name=userName type=text id=userName size=15 maxlength=5>
密碼:<input name=userPass type=password id=userPass size=15 maxlength=15>
<input type=submit name=Submit value=Login>
</form>
</body>
</html>
完成後在新建一個loginCONN.asp檔案複製下面的程式碼保存!是連接資料庫的,這個我就不多解釋了…
<%
Dim CONN_Net118
Dim Conn_T
Dim mmdd
mmdd=onlyNet118.mdb
Set CONN_Net118 = Server.CreateObject(ADODB.Connection)
Conn_T=Provider=Microsoft.Jet.OLEDB.4.0;Data Source= & Server.MapPath(&mmdd&)
on error resume next
CONN_Net118.Open Conn_T
%>
下面我們來做一個loginPost.asp檔也存在這個目錄下,這個比較關鍵,仔細看下面的程式碼:
<!--#include file=loginCONN.asp -->
<%
'刪除maxTime時間內部活動的使用者,maxTime 在loginCONN.asp檔案裡面已經定義好了
Conn_Net118.Execute(Delete From onlyLogin where DATEDIFF('s',OLtime, now()) > & maxTime & )
'================================================== ===============
Dim rs, ts, txt, sql, userName, userPass
if Request.Form(Submit)=Login then
userName=Request.Form(userName)'取得表單使用者登陸名
userPass=Request.Form(userPass)'取得表單使用者登陸密碼
'由於我們在這裡討論的不是安全性問題所以用戶密碼都沒有加密
Set rs = Server.CreateObject(ADODB.RECORDSET)
sql=SELECT * FROM users where userName = ' & userName & ' and userPass = ' & userPass & '
rs.Open sql, CONN_Net118,1,1
IF 不 rs.eof then
Call isOK(userName) ' 使用者名稱密碼正確呼叫次過程,isOK將會在下面的程式中自訂。
else
Response.Write(<a href=javascript:history.go(-1)>使用者名稱或密碼錯誤</a>)
Response.End()
end if
rs.Close
Set rs=Nothing
end if
Sub isOK(userName)
Dim Olip ' 資料庫中目前登陸使用者名稱保存的ip
Dim Oltime ' 資料庫中目前登陸使用者名稱保存的最後刷新網頁的時間,是計算使用者是否在線上的重要資料。
Dim OLip1 ' 記錄目前使用者登陸ip,用來區分是否為相同使用者的標示
OLip1=Request.ServerVariables(REMOTE_ADDR)'取得提交登陸資訊使用者的IP
Set ts=Conn_Net118.execute(Select * FROM onlyLogin WHERE OLname='& userName & ')
if not ts.eof then ' 查詢資料庫是否有此使用者的登陸過的信息
OLtime=ts(OLtime)
OLip=ts(OLip)
if OLip1<>OLip and DateDiff(s,OLtime,now()) < maxTime then
'上句判斷如果提交登陸用戶ip不是資料庫中最後紀錄的用戶ip並且
'使用者的最後活動時間和目前時間相隔並沒超過規定的秒數則確認此使用者目前在線
Response.Write <a href=javascript:history.go(-1)>此使用者目前在線,你無法從其他地方登陸此帳號! </a>
Response.End()
else
'否則的話判定登陸成功付值給session
Session(lgName)=userName
Session(lgPass)=userPass
Response.Redirect loginOK.asp
Response.End
end if
else
'如果資料庫沒有次登陸使用者紀錄則執行下面的語句
Dim ls
Set ls=Server.CreateObject(ADODB.RECORDSET)
ls.OpenSelect * From onlyLogin,CONN_Net118,2,2
ls.ADDNEW
ls(OLname)=userName
ls(OLip)=OLip1
ls(OLtime)=NOW()
ls.UPDATE
ls.Close
Set ls=Nothing
'判定登陸成功付值給session
Session(lgName)=userName
Session(lgPass)=userPass
Response.Redirect loginOK.asp
Response.End
end if
End Sub %>
如果你看得懂asp檔一看就知道登陸成功後葉面會跳到loginOK.asp下面我們馬上看看這個葉面的程式碼吧
<style type=text/css>
<!--
body {background-color: #FF9900;}
-->
</style>
<% IF Session(lgName)<> then %>
您登陸成功了! ! !以下是潛入網頁內的iframe為的是在規定的時間刷新網頁向伺服器報告你是否在線
為了方便區分,frame網頁我們採用了白色作為底色
<iframe border=0 name=new_date marginwidth=0 framespacing=0 marginheight=0 src=loginFrame.asp
frameborder=0 noResize width=100 scrolling=no height=30 vspale=0></iframe>
<% else %>
您沒有登陸哈歡迎光臨站長資訊網:http://www.Net118.com
<% end if %>
如果你是細心之人馬上就知道下面我要做的是loginFrame.asp
<!--#include file=loginCONN.ASP -->
<% CONN_Net118.Execute(Update onlyLogin Set OLtime='& NOW() & ' where OLname = ' & Session(lgName) & ') %>
<html><head><meta http-equiv=refresh content=<%=(maxTime-5)%>; url=></head></html>
好了到此為止我們的程序就完成了,這個程序的關鍵就是判定用戶是否在線,而我也是無可奈何的是用了FRAME把定時刷新確定用戶在線的關鍵性葉面嵌套在主程序的葉面裡,實際的操作你可以把那個iframe的寬和高改為0讓一般用戶看不到,或者讓主程式的網頁底色和那個嵌套進來的定時刷新的網頁一樣就ok了。
前不久在討論區看到有人說用session和cookies之類的東西也能判定,這顯然是不可能的呀,因為他們生成的對像都是對自己起作用的,其數據內容根本無法和其他用戶共用。 appliaction應該是實現這一目的的另一種方法,但是我一想到如果同是有很多用戶登陸要為每個用戶生成至少一個到三個appliaction對象就放棄了這個念頭,因為那樣我們原本可憐的服務器一定會被拖垮~