本文的目的在於提供一種可行的解決方案通過Web Service技術來整合和管理現有的Asp程式到Asp.Net。 此應用解決
方案儘可能從實際出發以迭代更新方式的策略把Asp Web伺服器記憶體中的當前Session更新到Asp.Net。
背景:
現有公司的產品OA是採用asp早先的技術開發,需要與目前最新的asp.net產品進行資料互動的應用。現有的asp應用程式
往往採用“ASP sessions”,這是一種經典的asp內建模式,即允許資料臨時暫存在web伺服器記憶體中,其最大的限制因素就
是asp的session狀態是依賴具體的伺服器。而另一個更寬範圍的解決方案就是很多web伺服器都可能別用於根據請求而指向的
任何網路伺服器。實際上就是所有的web伺服器都像在一個農場中,因而任何在記憶體中的session狀態將不會自動跟隨請求。每
個asp伺服器提供自己的session狀態,除非使用者很湊巧的返回統一伺服器,造成系統session丟失。
通過使用伺服器管理產品(如bigip)來強制使用者會同意伺服器內的web農場來解決記憶體中asp seesion因伺服器關係而造
成的問題。為了達到這個目的,採用一個cookie在用戶端工作,在伺服器端來使用,讓使用者直接可以回到同一個伺服器上的
每個reqeust。這樣可以限制擴充性,提高可維護性,避免伺服器故障的風險(例如:session丟失伺服器 失敗)。
微軟Asp.net技術的出現終於解決了這個問題,可以讓我們來儲存session資訊到web server和database或者其他域
server。不錯,問題解決了,我們還有必要用asp代碼嗎?全部扔掉?如果這樣做的話就會需要很大代價去重新使用.net來
重寫asp。看來還是不可行。另一種比較好的解決方案就是用迭代方法來部分移植代碼到新的模型勝過重寫asp代碼,在這
個過程中如果舊的ASP代碼和新的asp.net代碼可以有一個共同的session狀態而保持正常的工作,那麼在整個生命週期中
將會有益於你更好的規避風險.以下提供了幾個解決方案從此略上來解決當採用經典的asp sesssion因伺服器關係而造成的
問題。
1、使用者自訂群組或者使用Asp/ADO指令碼去實現直接讀寫使用者session資料到資料庫;
2、使用者自訂群組件去直接存取asp.net seesion資料;
3、通過web servieces建立asp到asp.net的橋共用session;
在本文中,我們將討論最後一種方案,其中也會包括一些web services與asp/ADO定製資料庫,和asp session 池的基本
效能資料比較,呵呵...看完後你自己選擇用哪個。
ASP to ASP.NET Bridge / Web-Service 方案
此方案中只是簡單的實現了一個從asp到asp.net的web services橋樑,如果你需要用資料庫,只需要進行簡單的配置(web.
congfig和aspState 資料庫)。代碼中用來獲得和設定session資料的方法寫在一個javascirpt中,該檔案必須儲存在本地asp
程式中。
此javascirpt實現MSXML, http功能以便和server端互動,並負責將這些cookie回收給使用者工作站。
優點:
支援與伺服器無關的web-farm部署,提高可擴充性簡單的實現asp和asp.net的共同session狀態松耦合,以sessioni管理
(不需連線的HTTP介面, 80連接埠,可防火牆等)利用久經時間考驗的asp.net session實施。
缺點: 比asp session 記憶體池實現和資料庫實現會慢。
Asp記憶體共用機制:
Session是採用類似字典或者雜湊表的形勢儲存在web server記憶體中,ASP會保持session狀態,提過一個特別的key給
使用者,當session會話開始時,這個key將儲存cookie來紀錄用戶端發送到伺服器的每一項請求,在伺服器端,獲得cookie
的key,就可以知道request對應的session.這種機制的一個明顯的優勢就是速度和方便,所有的session都會在一台伺服器上
儲存,所以很開,但是正如前面所說的,將資料儲存在一台伺服器也是一個重大缺點,迫使使用者返回同一台伺服器檢索
session資料。這個減少了webform的優勢,它只是一種低成本,大淘汰的策略,如果你只想實現簡易功能,就可以用它。
優點:
記憶體紀錄seesion,速度快,使用標準的ASP代碼基礎利用久經時間考驗的ASP session實施。
缺點:
它承載的能力有限,無法大規模開展網路農場(伺服器依賴度高) ,伺服器故障導致session丟失,記憶體佔有率太大。
Asp/ADO資料庫實現解決方案
建立了一個資料庫連接之間的ASP應用伺服器和資料庫伺服器。使資料被存在一個中央資料庫或者資料庫叢集,然後分
別從不同的伺服器上的asp程式執行。本文種只給出方案。擷取和設定session的代碼可以被放進一個javascirpt檔案中,支
持基於webservices擷取的方法,允許asp取代javascirpt定製資料庫模式,直接存取asp.netsession資料(如建立aspstate
資料庫)。
優點:
1、支援不依賴伺服器的webform部署;
2、比asp.net Web服務更快;
缺點:
1、代碼為定製執行(比較死板);
2、比記憶體共用ASP sessions 慢;
3、需要資料庫連接,從網路伺服器到資料庫伺服器;
效能:
在下面資料中,列出了每種方案的效能比較,強調的是記憶體共用aspsession池最快小型使用者可以使用,採用資料庫的話
也會增加額外的開支,增加成本(除非你很有錢)。減 少網路回傳,伺服器請求是提高效能的唯一方法,微軟的Web應用程
序壓力工具,是用來執行測試壓力水平的25個線程為1分鐘的時間從表中可以明顯的看出用記憶體儲存aspsession比另外兩種方
式更快。
Method Get Data (ms) Set Data (ms)
5 values 1 value 5 values 1 value
In-memory ASP Sessions 46 9 34 7
ASP/ASP.NET web service individually 4321 864 3397 679
ASP/ASP.NET web service grouped 711 142 990 198
ASP/ADO database individually 346 69 841 168
ASP/ADO database grouped 163 33 860 172
代碼描述ASP機制,在asp中建立sessioni 如下:
Session("Sky") = "Blue";
在其他的頁面中訪問這些值採用:
var skyString = Session("Sky");
新的API文法:
下面的文法將會代替原來的asp session 文法,目的是在橋的使用中javascript 函數可以進行封裝
設定一個關索引值對;
設定一個kye-value 類型session 資料,文法和值錢的asp Session 文法很相似,採用下面的代碼可以把現有的設定asp session代碼替換;
設定sessioni資料:
SetSessionValue("Sky", "Blue");
擷取 session :
var SkyString = GetSessionValue("Sky");
這種方法建議在設定比較少的情況下用
設定多個key-valus對值
這些方法的最大開銷在於設定每一個key-value,然後返回給webservice,推薦用以下方法來設定(當超過3對以上的key-values)
設定session
var sessionInfo = NewSession();
sessionInfo.Add(“Sky”, "Blue");
sessionInfo.Add(“Grass”, “Green”);
SetSession(sessionInfo);
獲得session
var sessionInfo = GetSession();
var skyString = sessionInfo.Item(“Sky”);
var grassString = sessionInfo.Item(“Grass”);
Java Script Example
<%@ Language="JScript" %>
<script language="JScript" runat="server" src="ASPSessionWS.js" />
<%
var sessionInfo = NewSession();
sessionInfo.Item("Sky") = "Blue";
sessionInfo.Item("Grass") = "Green";
SetSession(sessionInfo);
var retrievedSession = GetSession();
var sSky = retrievedSession.Item("Sky");
var sGrass = retrievedSession.Item("Grass");
Response.Write(sSky + "<br>");
Response.Write(sGrass + "<br>");
%>
Visual BASIC Example
<%@ Language="VBSCRIPT" %>
<script language="JScript" runat="server" src="ASPSession.js" />
<%
Dim sessionInfo
Set sessionInfo = NewSession()
sessionInfo.Item("Sky") = "Blue"
sessionInfo.Item("Grass") = "Green"
SetSession(sessionInfo)
Dim retrievedSession
Set retrievedSession = GetSession()
Dim sSky
sSky = retrievedSession.Item("Sky")
Dim sGrass
sGrass = retrievedSession.Item("Grass")
Response.Write(sSky & "<br>")
Response.Write(sGrass & "<br>")
%>
Web Service 實現代碼
此webservice有4個簡單方法組成,它支援再asp.net sessioni中設定和獲得單獨的values,以及簡化通過裝載xml來設定
session變數的複雜度。
public string getSessionValue(string sessionVariable)
public bool setSessionValue(string sessionVariable, string sessionValue)
public string getSessionValues()
public bool setSessionValues(string xmlSessionValues)
為了讓asp.net web service能夠來支援建立和維護sessions,要通過下麵包含在每個方法中的屬性,這將返回一個asp.net_
sessionID的cookie到響應中可以作為使用asp Session代碼的橋。
[WebMethod(EnableSession=true)]
你也可以增加很多webservices介面來實現其他你想要的功能。
ASP 橋的實現:
Asp端的橋,其實就是一個依賴msxml2.serverXMLhttp COM介面為訪問web services的服務端和Scripting.Dictionary 提
供一個雜湊表。在當前頁中保持一個臨時的副本session.
var xmlHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");
xmlHTTP.open("POST", sURL, false);
var clientCookie = "" + Request.Cookies("ASP.NET_SessionId");
xmlHTTP.setRequestHeader("cookie", "ASP.NET_SessionId=" +
clientCookie + "; path=/;");
.
.
.
Response.Cookies("ASP.NET_SessionId") = httpCookie;
字典對象轉化
var dctSession = new ActiveXObject("Scripting.Dictionary");
var re = new RegExp("<SessionItem ", "g");
部署
檔案aspseesionws.js必須放在asp程式下,並且在asp.net程式中寫上如下代碼
<script language="”Jscript”" runat="”server”" src=”\Script\ASPSessionWS.js” >
</script>
採用80連接埠訪問web server,在指令檔中寫如下函數,用來維護session狀態
function GetWebService(Function, Parameters)
{
var xmlPayload = "";
var sURL = "http://www.xxxx.com/ASPBridge/bridge.asmx" + "/" +
Function;
總之,採用webservice 建立從遺留的asp session 到新的asp.net 的session,只要的目的是為了採用新的技術整合舊的程式,
允許2個程式共用一個session內容,雖然效能很重要,但是目前還沒有更完美的方法完全的把原有程式整合進.net。
樣本下載:ASPBridge.rar (5.59 kb)