一個總店與多個分店的情況,要求每天分店將業務資料上傳到總店
1. 伸縮性
伸縮性是衡量應用在同一時間內能夠處理多少使用者的尺度。也是反映應用程式能否滿足重要應用的一個指標。
在你的應用程式中到底可以容納多少使用者,每個使用者每隔多久向伺服器提交一次請求,你的使用者所處的位置,如區域網還是interner中。這些問題在設計應用的時候,你需要考慮。
在設計分散式應用之前,一個問題就是使用的協議。如DCOM、HTTP和MSMQ。
DCOM的缺點是顯著的。如不能穿越防火牆。不能利用基於請求的負載平衡技術,因而限制了併發使用者的數量,還要對每臺客戶機進行大量的配置等等。
HTTP實現簡單及各個平臺的支援越來越受到歡迎。事實上,構建COM+體系結構是建立在下面這個基礎之上的:一個應用必須使用HTTP來實現客戶到服務的通訊才能獲得最大的伸縮性。
2. 實際的問題
經常我們會遇到這樣的問題,如一個總店與多個分店的情況,要求每天分店將業務資料上傳到總店。彼此相隔較遠。
總店的環境:有自己的固定IP 的WEB伺服器(或者沒有固定IP)的,或者沒有自己的伺服器,僅僅有一個虛擬空間的網站。
分店的環境:可以通過撥號方式連線。
3.達到的要求
總店每天可以通過網站及時的看到分店的情況。並且資料要做到本地保留。
4.常見的解決辦法
最多的一種方式就是分店將資料匯出成txt檔案,撥號連線成功後,將txt傳送到某個ftp目錄或者傳送到指定的Email裡。總店手工接收或者程式接收後,再做處理。
還有一種就是分店的資料庫直接連線總店的資料庫,做儲存更新操作。
5.使用HTTP和XML來實現
就是客戶端應用程式通過一個XML文件傳遞引數,向Web伺服器提交一個HTTP請求。服務端使用一個Asp頁面得到該引數,執行其方法,然後使用XMl文件向客戶端返回資料。
先看看服務端ASP的程式碼:
1).從服務端返回資料
getinfo.asp(以流的方式返回記錄集)
<%@ Language=VBScript %>
<%
set conn=Server.CreateObject("ADODB.connection")
conn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & Server.MapPath("web.mdb")
dim rs
Set rs = Server.CreateObject("ADODB.Recordset")
rs.open "select * from test",conn
rs.save response,1
rs.close
%>
這裡說明一下:只要客戶端在請求中傳送了符合格式的XML文件,ASP中的Request和Response物件就能工作。(這項技術只能在IIS5和Windows 2000中以及各自的高版本中使用。)
在客戶端使用vb
'引用microsoft activex data object 2.x library
‘引用microsoft XML,version2.0
Option Explicit
Private rs As ADODB.Recordset
'從遠端資料庫得到內容
Private Sub Command5_Click()
‘提交一個HTTP請求。
Set rs = New ADODB.Recordset
rs.Open "http://localhost/webxml/getinfo.asp"
Set DataGrid1.DataSource = rs
End Sub
2)單個記錄提交到遠端asp檔案
Getsingleinfo.asp(資料增加並返回結果)
<%@ Language=VBScript %>
<%
'這裡需要修改,返回客戶的xml響應文件
Response.ContentType = "text/xml"
set conn=Server.CreateObject("ADODB.connection")
conn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & Server.MapPath("web.mdb")
dim xmldom
' set xmldom = Server.CreateObject("Microsoft.XMLDOM")
set xmldom = Server.CreateObject("MSXML.DOMDocument")
xmldom.load Request
dim sid,name,price,catagory,pdate
sid = xmldom.selectSingleNode("//專案編號").text
name = xmldom.selectSingleNode("//專案名稱").text
price = xmldom.selectSingleNode("//價格").text
catagory = xmldom.selectSingleNode("//種類").text
pdate =xmldom.selectSingleNode("//發生日期").text
dim strsql,retval
on error resume next
strsql="insert into test(sid,name,price,catagory,pdate) values('"& sid &"','"& name &"','"& price &"','"& catagory &"','"& pdate &"')"
'response.write strsql
conn.execute strsql
if err.number=0 then
retval="資料成功提交"
else
retval="資料提交失敗,請檢查你的資料"
end if
set xmldom = Nothing
set conn=nothing
'下面的程式碼是將結果以xml形式返回
'需要加上<?xml version="1.0" encoding="gb2312"?>這句,否則無法返回中文
%>
<?xml version="1.0" encoding="gb2312"?>
<Response>
<retval><%=retval%></retval>
</Response>
相應的客戶端vb程式碼:
Private Sub Command3_Click()
Dim httpRequest As MSXML.XMLHTTPRequest
Set httpRequest = New MSXML.XMLHTTPRequest
Dim StrXml As String
'構造出要上傳的XML串,這裡節點使用中文
StrXml = "<Request>" & _
"<專案編號>" & Txtbh.Text & "</專案編號>" & _
"<專案名稱>" & Txtname.Text & "</專案名稱>" & _
"<價格>" & Txtprice.Text & "</價格>" & _
"<種類>" & TxtCategory.Text & "</種類>" & _
"<發生日期>" & Txtpdate.Text & "</發生日期>" & _
"</Request>"
httpRequest.Open "POST", "http://localhost/webxml/putsingleinfo.asp", False
httpRequest.send StrXml
'如果錯誤
If httpRequest.Status <> 200 Then
MsgBox httpRequest.statusText, , httpRequest.Status
Exit Sub
End If
'以下是判斷資料是否正確提交
Dim strretval As String
Dim ResponseXml As DOMDocument
Set ResponseXml = New DOMDocument
Set ResponseXml = httpRequest.ResponseXml
strretval = ResponseXml.selectSingleNode("//retval").Text
MsgBox strretval
End Sub
3)多條資料上傳
putinfo.asp
<%@ Language=VBScript %>
<!--#include file="adovbs.inc"-->
<%
Response.ContentType = "text/xml"
set conn=Server.CreateObject("ADODB.connection")
conn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & Server.MapPath("web.mdb")
dim rs
on error resume next
Set rs = Server.CreateObject("ADODB.Recordset")
dim xmldom
' set xmldom = Server.CreateObject("Microsoft.XMLDOM")
set xmldom = Server.CreateObject("MSXML.DOMDocument")
xmldom.load Request
dim sid,name,price,catagory,pdate
Set xmlNode = xmlDom.documentElement
Set objRetValNode = xmlDom.documentElement
For i = 0 To xmlNode.childNodes.length - 1
sid = xmlnode.childNodes(i).childNodes(0).Text
name = xmlnode.childNodes(i).childNodes(1).Text
price = xmlnode.childNodes(i).childNodes(2).Text
catagory = xmlnode.childNodes(i).childNodes(3).Text
pdate = xmlnode.childNodes(i).childNodes(4).Text
strsql="insert into test(sid,name,price,catagory,pdate) values('"& sid &"','"& name &"','"& price &"','"& catagory &"','"& pdate &"')"
'response.write strsql
conn.execute strsql
next
if err.number=0 then
retval="資料成功提交"
else
retval="資料提交失敗,請檢查你的資料"
end if
set conn=nothing
%>
<?xml version="1.0" encoding="gb2312"?>
<Response>
<retval><%=retval%></retval>
</Response>
相應的vb客戶端程式碼
Private Sub Command2_Click()
Dim rs1 As New ADODB.Recordset
rs1.CursorLocation = adUseClient
rs1.CursorType = adOpenKeyset
rs1.LockType = adLockBatchOptimistic
rs1.Open "select * from test", conn, adOpenDynamic, adLockPessimistic
'由於RequestXml所包含的東西過多,我們直接生成xml檔案
'直接使用了資料庫欄位,沒有使用中文命名
Dim strXML
Dim fm
strXML = "<xml>"
rs1.MoveFirst
Do While Not rs1.EOF
strXML = strXML & "<row>"
For Each fm In rs1.Fields
strXML = strXML & "<" & fm.name & ">" & fm.Value & "</" & fm.name & ">"
Next
strXML = strXML & "</row>"
rs1.MoveNext
Loop
strXML = strXML & "</xml>"
Set rs1 = Nothing
Dim httpRequest As New MSXML.XMLHTTPRequest
httpRequest.Open "POST", "http://localhost/webxml/putinfo.asp", False
httpRequest.send strXML
If httpRequest.Status <> 200 Then
MsgBox httpRequest.statusText, , httpRequest.Status
Exit Sub
End If
Set rs = New ADODB.Recordset
'重新載入
rs.Open "http://localhost/webxml/getinfo.asp"
Set DataGrid1.DataSource = rs
'以下是判斷資料是否正確提交
Dim strretval As String
Dim ResponseXml As DOMDocument
Set ResponseXml = New DOMDocument
Set ResponseXml = httpRequest.ResponseXml
strretval = ResponseXml.selectSingleNode("//retval").Text
MsgBox strretval
End Sub
結束語:
這個例子充分的體現了HTTP和XML的優勢。對於客戶來說,可以訂製自己的xml格式,清晰易懂。安全性大大的提高。而且可以在不同的應用伺服器上加以擴充套件使用。
如果要提高效能和加大安全性,在服務端可以使用COM元件來擴充套件ASP,以達到最好的效果。