Cơ sở dữ liệu
5.8 TÍNH MỞ CỦA DỊCH VỤ
Như đã trình bày ở chương 4, một chỉ tiêu quan trọng đối với hệ thống là phải có tính mở về mặt dịch vụ, nghĩa là người quản lý có thể dùng mơđun quản lý (ADMIN) để tạo ra các dịch vụ mới theo nhu cầu mà không yêu cầu phải sửa đổi mã nguồn của chương trình.
Để làm được điều này, cần phải có một cơ sở dữ liệu chứa quan hệ giữa mã lệnh và dịch vụ. Cơ sở dữ liệu quan hệ này được gọi là “cơ sở dữ liệu dịch vụ” và có dạng như trong hình dưới đây.
Hệ thống nhắn tin nội bộ trên cơ sở ghép nối môđem GSM ứng dụng SMS
Trong cơ sở dữ liệu trên, trường ServCMD tương ứng với lệnh dịch vụ.
Khi đó, hoạt động với từng dịch vụ này có thể được minh hoạ theo các bước dưới đây:
1. Nhận tin nhắn.
2. Xử lý nội dung tin nhắn để xác định được lệnh dịch vụ.
3. So sánh lệnh dịch vụ với cơ sở dữ liệu dịch vụ để tìm ra các tên của cơ sở dữ liệu chứa dữ liệu dịch vụ đồng thời xác định các trường index tương ứng. Nếu lệnh dịch vụ khơng nằm trong cơ sở dữ liệu thì trả lời với một tin nhắn trợ giúp.
4. Truy vấn cơ sở dữ liệu nhận được qua bước 3 kể trên để tìm được thơng tin theo lệnh yêu cầu.
5. Gói thơng tin thu được thành tin nhắn và gửi trả lại người gửi.
Như vậy, bằng cách này, ta có thể tạo ra những dịch vụ mới bằng cách thêm vào cơ sở dữ liệu những lệnh mới với các quan hệ mới. Đoạn chương trình dưới đây minh họa kỹ thuật đã được sử dụng để tạo tính mở của dịch vụ:
Dim LookupDBS As Database Dim IndexTab As Recordset
Set LookupDBS = OpenDatabase("..\Databases\ServiceList.mdb") sqlstr = "select * from ServiceList where ServCMD = " & "'" &
ServCMD & "'"
Set IndexTab = LookupDBS.OpenRecordset(sqlstr, dbOpenDynaset) If IndexTab.RecordCount <> 0 Then db_name = IndexTab("DB_name") tab_name = IndexTab("Tab_name") IndexCol = IndexTab("IndexField") DescpCol = IndexTab("Description") IndexTab.Close LookupDBS.Close Else IndexTab.Close
SMSTxT = "Khong co lenh " & ServCMD & ". Soan tin 'HELP' de kiem tra cac lenh co the dung!"
ReturnSMS
LookupDBS.Close Exit Sub
End If
Trong đoạn mã trên, sau khi lệnh dịch vụ ServCMD đã được tách ra từ tin nhắn đến, nó sẽ được kiểm tra với cơ sở dữ liệu chứa các lệnh dịch vụ có tên là
Hệ thống nhắn tin nội bộ trên cơ sở ghép nối môđem GSM ứng dụng SMS
cho dịch vụ tương ứng trong trường “DB_Name”, và thơng qua trường này, chương trình sẽ biết được là sẽ phải lấy thông tin từ bảng dữ liệu nào để trả lời dịch vụ, tất cả các thông số này sẽ được lưu vào các biến db_name, tab_name, IndexCol, DescpCol để sử dụng cho việc query dữ liệu trả lời được thực hiện sau đó. Việc sử dụng các biến này được minh họa ở đoạn chương trình tiếp theo dưới đây.
Trong trường hợp lệnh khơng có, chương trình sẽ soạn tin nhắn SMSTxT = "Khong co lenh " & ServCMD & ". Soan tin 'HELP' de kiem tra cac lenh co the dung!" và gửi đến số máy cần gửi thông qua chương trình con ReturnSMS.
Đoạn chương trình dưới đây minh họa việc query dữ liệu trả lời thông qua giá trị các biến db_name, tab_name, IndexCol, DescpCol đã tìm được ở trên, tùy thuộc vào lệnh được sử dụng:
Dim SeviceDBS As Database Dim LookupTab As Recordset
Set ServiceDBS = OpenDatabase(db_name) Select Case ServID
Case "LIST"
sqlstr = "select " & IndexCol & "," & DescpCol & " from " & tab_name
Goto Line2 End Select
Như vậy dòng lệnh query dữ liệu sqlstr tùy thuộc vào giá trị của tham số của lệnh cũng như thông số của lệnh như đã trình bày. Trong đoạn mã kể trên, chúng tơi chỉ đưa ra ví dụ khi thơng số của lệnh là “LIST”, khi đó chương trình sẽ liệt kê toàn bộ nội dung cột index và cột description trong cơ sở dữ liệu rồi gửi tới người yêu cầu thông qua tin nhắn.
5.9 CHAT
Nhằm trao đổi thơng tin với các máy tính nối mạng khác để thực hiện tính năng chat, tập Winsock trong Visual Basic được sử dụng, giao thức trao đổi thông tin là TCP.
Sở dĩ giao thức TCP được chọn là nhờ khả năng hỗ trợ phương thức trao đổi thông tin theo kiểu Client-Server mà ứng dụng trên Server không cần phải khai báo
Hệ thống nhắn tin nội bộ trên cơ sở ghép nối môđem GSM ứng dụng SMS
địa chỉ của các máy trạm, chỉ có các máy trạm là cần phải khai báo địa chỉ của máy chủ.
Sử dụng tập Winsock của Visual Basis, ta có thể thiết lập các ứng dụng Client-Server như sau:
Máy chủ:
tcpServer.LocalPort = 1001 tcpServer.Listen
Tập Winsock được dùng trên server được đặt tên là tcpServer, sau thiết lập ở trên máy chủ sẽ lắng nghe các thông tin được gửi đến cổng 1001 như ở trên.
Tuy nhiên, như chúng ta đã biết, TCP là một giao thức định hướng kết nối, vì vậy, máy chủ cần phải chấp nhận các yêu cầu kết nối từ máy trạm, việc này được thực hiện thông qua đoạn chương trình sau:
Private Sub tcpServer_ConnectionRequest _ (ByVal requestID As Long)
If tcpserver.State <> sckClosed Then _ tcpserver.Close
tcpserver.Accept requestID End Sub
Đọc thông tin đến và gửi thông tin đi được thực hiện qua các lệnh sau:
tcpServer.GetData strData „ Đọc thông tin đến tcpServer.SendData txtSend „ Gửi thông tin đi
Máy trạm
Trên các máy trạm, địa chỉ của Server cần được khai báo, trong chương trình này, địa chỉ của máy chủ được đọc vào từ file CommConfig.ini. Sở dĩ chúng tôi dùng cách này là vì địa chỉ máy chủ có thể thay đổi (tùy thuộc vào cơ quan nó được đặt) và ta có thể dễ dàng thay đổi cấu hình thơng qua file .ini đó mà khơng cần phải thay đổi mã nguồn của chương trình. Với các máy trạm, ta thiết lập kết nối TCP như sau:
tcpClient.RemoteHost = "Lap-Hai-IBM" tcpClient.RemotePort = 1001
tcpClient.Connect
Với máy trạm, khi muốn kết nối cần phải có thủ tục connect (do TCP là giao thức định hướng kết nối). Khi thủ tục connect được thực hiện, nó sẽ
Hệ thống nhắn tin nội bộ trên cơ sở ghép nối môđem GSM ứng dụng SMS
gửi connect request đến máy chủ đã được khai báo và kết nối chỉ được thực hiện khi máy chủ chấp nhận. Sau khi đã thiết lập kết nối, việc gửi và nhận thơng tin hồn tồn giống như đã đề cập ở phần máy chủ.
Tuy nhiên, khi Chat, đầu tiên người dùng phải login, tức là phải gửi các thông tin về username và mật khẩu về máy chủ, điều này được thực hiện như sau:
UserId = UCase(txtUserName.Text) Dim SendString
SendString = "UID:" & txtUserName.Text & ";PWD:" & txtPassword.Text
tcpClient.SendData SendString
Như vậy, luồng thơng tin gửi tới máy chủ sẽ có dạng: UID:<username>;PWD:<password>
Máy chủ sau khi nhận được thông tin này sẽ kiểm tra với cơ sở dữ liệu để xem xét việc login là có hợp lệ khơng, và gửi trả lại thông tin hợp lệ hoặc không hợp lệ: If ADBMobNo.RecordCount = 0 Then ClientStr = "Wrong_UID!" tcpServer.SendData ClientStr Exit Sub End If
If Trim(PWD) = Trim(password) Then ClientStr = "Login_OK!" tcpServer.SendData ClientStr Else ClientStr = "Wrong_PWD!" tcpServer.SendData ClientStr End If
Sau khi đã login thành cơng, vấn đề quan trọng là phải duy trì được thơng tin giữa máy chủ và máy trạm. Để có thể chat được với mobile, mỗi gói thơng tin chat gửi đi từ máy trạm tới máy chủ bao giờ cũng gồm ba thành phần: username, số máy cần gửi và thông tin cần gửi. Máy chủ, sau khi nhận được thông tin này, dựa trên thông tin về username, sẽ viết thông tin này vào cơ sở dữ liệu CHATOUT. Một chương trình con khác trên Server sẽ làm nhiệm vụ hỏi vòng cơ sở dữ liệu CHATOUT này và gửi tin nhắn đi thông qua mođem GSM kết nối với máy chủ.
Đồng thời, các tin nhắn CHAT được gửi tới thông qua sms sẽ bao gồm thông tin về user và nội dung tin gửi. Như đã trình bày ở phần 5.7, các tin này sẽ được lưu
Hệ thống nhắn tin nội bộ trên cơ sở ghép nối môđem GSM ứng dụng SMS
vào cơ sở dữ liệu CHATIN. Phần mềm trên Server sẽ hỏi vòng cơ sở dữ liệu này để kiểm tra xem có tin nhắn mới nào đến user ở máy trạm mà chưa được chuyển đến máy trạm, nếu có, nó sẽ chuyển tới máy trạm thông qua thủ tục gửi dữ liệu tcpServer.SendData.
5.10 THỐNG KÊ
Dữ liệu thống kê là một tiêu chí quan trọng của bất kỳ hệ thống viễn thơng nào vì các dữ liệu thống kê là cơ sở rất quan trọng trong việc đánh giá hoạt động của hệ thống, qui hoạch dung lượng cho hệ thống cũng như dự báo sự nhu cầu phát triển.
Sử dụng các mã trả lại của môđem sau mỗi lệnh gửi hoặc nhận tin nhắn, ta có thể đếm được số tin nhắn đã nhận về hoặc gửi đi thành công hay không thành công. Lưu số đếm này vào biến hệ thống rỗi ghi ra sau mỗi giờ, ta sẽ thu được dữ liệu thống kê theo giờ. Đoạn mã dưới đây minh hoạ cách làm này:
If SentOK Then
OtherReturnOK = OtherReturnOK + 1 Else
OtherReturnFail = OtherReturnFail + 1 End If
Trong đoạn chương trình kể trên, giá trị của bộ đếm OtherReturnOK tăng lên một mỗi khi một tin nhắn tương ứng được gửi thành công, và bộ đếm OtherReturnFail sẽ tăng một đơn vị nếu tin nhắn không được gửi thành công. Tuy nhiên, giá trị của bộ đếm sẽ phải được ghi ra và reset sau mỗi giờ.
Để giúp người vận hành hệ thống dễ kiểm tra dữ liệu thống kê, các dữ liệu thống kê phải được đưa ra dưới dạng file có ngày giờ rõ ràng.
Việc ghi ra các thống kê theo giờ là một công việc khá phức tạp vì kỹ thuật hỏi vịng giờ hệ thống cũng như số ngày trong tháng, năm có phải là năm nhuận hay khơng v.v...Đoạn chương trình dưới đây minh họa cách làm này, trong file thống kê được ghi ra Statsfile có dạng .csv và có thể đọc dễ dàng bằng MS Excel:
Do
StatsTimer = Hour(Time) Wait
If CounterOn.Value = 1 Then
If Trim(Hour(Time)) <> Trim(StatsTimer) Then Counters End If
Hệ thống nhắn tin nội bộ trên cơ sở ghép nối môđem GSM ứng dụng SMS
Private Sub Counters() IntDate = Day(Date) IntMonth = Month(Date) IntYear = Year(Date) IntEndTime = Hour(Time) If IntEndTime = 0 Then IntStartTime = 23 If IntDate = 1 Then
Select Case IntMonth Case 1 IntDate = 31 IntMonth = 12 IntYear = IntYear - 1 Case 2, 4, 6, 8 IntDate = 31 IntMonth = IntMonth - 1 Case 3
If IntYear Mod 4 = 0 Then IntDate = 29 Else IntDate = 28 End If IntMonth = IntMonth - 1 Case Else IntDate = 30 IntMonth = IntMonth - 1 End Select End If Else IntStartTime = Hour(Time) - 1 End If
StatsFile = "../Counters/Stats " & IntDate & "-" & IntMonth & "-" & IntYear & ".csv"
CheckFile = Dir(StatsFile)
If (Trim(CheckFile) & "") = "" Then Open StatsFile For Append As #1 Print #1, "StartTime,EndTime," & _
"InAucRRecv,HelpRecv,ChatRecv,OtherRecv," & _ "ChatReturnOK,ChatReturnFail,HelpReturnOK,HelpReturnFail,Othe rReturnOK ,OtherReturnFail," & _
"OperatorSendOK,OperatorSendFail" Print #1, IntStartTime & "," & IntEndTime & "," & _ InAucRRecv & "," & HelpRecv & "," &
ChatRecv & "," & OtherRecv & "," & _
ChatReturnOK & "," & ChatReturnFail & "," & HelpReturnOK & "," & _
HelpReturnFail & "," & OtherReturnOK & "," & OtherReturnFail & "," & _
OperatorSendOK & "," & OperatorSendFail Close #1
Else
Open StatsFile For Append As #1
Hệ thống nhắn tin nội bộ trên cơ sở ghép nối môđem GSM ứng dụng SMS
InAucRRecv & "," & HelpRecv & "," & ChatRecv & "," & OtherRecv & "," & _
ChatReturnOK & "," & ChatReturnFail & "," & HelpReturnOK & "," & _
HelpReturnFail & "," & OtherReturnOK & "," & OtherReturnFail & "," & _
OperatorSendOK & "," & OperatorSendFail Close #1
End If
„Reset all counters to Zero InAucRRecv = 0 ChatReturnOK = 0 ChatReturnFail = 0 HelpReturnOK = 0 HelpReturnFail = 0 OtherReturnOK = 0 OtherReturnFail = 0 HelpRecv = 0 ChatRecv = 0 OtherRecv = 0 OperatorSendOK = 0 OperatorSendFail = 0 End Sub 5.11 LOG FILE
Nhằm giúp người quản lý hệ thống có thể phát hiện các lỗi hệ thống và kịp thời xử lý các lỗi có thể xảy ra (chẳng hạn cơ sở dữ liệu bị corrupt), chương trình cần được trang bị khả năng ghi lỗi. Các lỗi sẽ được ghi ra dưới dạng file có đi .log. Một bộ ghi lỗi sẽ được thực hiện trong tất cả các chương trình con nhằm đảm bảo tất cả các lỗi sẽ được ghi lại:
On Error GoTo LineErr
Chương trình ghi lỗi được minh họa dưới đây:
If Err.Number <> 0 Then
MsgEr = "Error # " & Str(Err.Number) & " was generated by " _
& Err.Source & Chr(13) & Err.Description Err.Clear
Open "..\Logs\SMSFE.log" For Append As #2 Print #2, Now() & " " & MsgEr
Close #2 End If
File log được ghi thành SMSFE.log, mỗi lỗi đều được ghi lại lỗi số, mô tả lỗi và thời điểm phát sinh lỗi (Now()).
Hệ thống nhắn tin nội bộ trên cơ sở ghép nối môđem GSM ứng dụng SMS
6.Chương 6