福建省氣象信息中心 楊賢棟 鄭志興 田功平
?
基于消息監(jiān)聽機制的氣象雷達資料推送應用實踐
福建省氣象信息中心 楊賢棟 鄭志興 田功平
針對省、市、縣對氣象資料快速共享的需求,該文采用與常規(guī)共享不同的方式,綜合利用網(wǎng)絡通信、數(shù)據(jù)交換、文件監(jiān)聽、數(shù)據(jù)庫等技術,設計并實現(xiàn)了基于消息監(jiān)聽機制的雷達資料快速推送系統(tǒng),在業(yè)務應用中表明,該系統(tǒng)穩(wěn)定性好、推送資料時效性高,能夠滿足業(yè)務應用需求。
氣象雷達資料 消息監(jiān)聽 數(shù)據(jù)交換 網(wǎng)絡通信
福建省地處中亞熱帶和南亞熱帶,地形復雜,氣候復雜,氣象災害頻發(fā),氣象災害種類繁多,每年受臺風、暴雨、干旱、大風、雷暴和冰雹等重大災害性天氣影響很大。僅在福建沿海登陸的熱帶風暴(臺風),一次就可以造成幾十億元、甚至上百億元的經(jīng)濟損失。在當前全球氣候變化背景下,極端氣候事件和突發(fā)性氣象災害對福建省農(nóng)業(yè)、水資源、交通、能源、糧食和國防的安全保障帶來了極大威脅。因此各地市、各縣市氣象局在氣象服務和防災減災方面承擔著極為重要的作用。為了能夠很好地服務廣大群眾、減少各方面的災害給人民帶來的損失,各地市氣象局需要及時、快速地發(fā)布準確的預報和預警,要達到這個目的,離不開準確、實時的氣象觀測資料,更離不開這些資料的快速共享。因此,將全省的雷達觀測資料、自動站等實時資料快速共享給地市和縣市具有重要意義。
目前,國內氣象部門在氣象資料共享方面主要依靠映射共享盤、Ftp方式輪回掃描讀取、Web共享[1-3]等方式。這些方式在共享的穩(wěn)定性和時效性方面難以滿足目前各地市、各縣市氣象部門在氣象資料快速共享方面的需求。因此,福建省氣象部門急需研究相關的資料推送技術,以實現(xiàn)雷達、自動站等實時性要求很高的資料快速共享,從而滿足各氣象部門在防災減災和氣象服務中的需求。
為了滿足上述氣象資料共享的需求,本文采取與常規(guī)共享方式不同的途徑,綜合利用網(wǎng)絡通信技術[4]、數(shù)據(jù)交換技術、文件監(jiān)聽技術、Web技術[5-6]、數(shù)據(jù)庫技術和軟件開發(fā)等技術,設計并實現(xiàn)了基于消息監(jiān)聽機制的雷達資料快速推送系統(tǒng),力爭雷達資料2min、自動站等其它資料3min內到達地市或縣市。
根據(jù)資料實時共享的需求,本項目采用基于文件監(jiān)聽的機制進行文件到達和修改的監(jiān)聽,并綜合利用網(wǎng)絡通信、數(shù)據(jù)交換、數(shù)據(jù)庫、Web等相關技術實現(xiàn)客戶端與服務端的通信,并自動下載定制好的資料至本地服務器進行共享。
1.1 系統(tǒng)架構設計
根據(jù)文件快速共享的目標和需求,將整個系統(tǒng)劃分為服務端和客戶端兩大部分。服務端監(jiān)聽信息中心服務器上文件到達的情況,形成相應的消息報文,通過原先建立好的網(wǎng)絡信道,將報文傳給客戶端??蛻舳烁鶕?jù)本地定制的配置需求過濾收到的消息報文。然后,下載自己需要的數(shù)據(jù)到本地服務器。系統(tǒng)整體架構圖如圖1所示。
1.2 系統(tǒng)功能設計
1.2.1文件監(jiān)聽功能
文件監(jiān)聽功能主要實現(xiàn)對雷達產(chǎn)品、雷達基數(shù)據(jù)、自動站資料、預警信號、部分服務產(chǎn)品進行實時監(jiān)聽。當服務器上有文件到達時,服務端軟件能夠實時監(jiān)聽到文件到達的消息。同時,在服務端界面上顯示響應的文件到達的相關信息,包括時間、文件名等。具體界面見圖2。
1.2.2一點對多點廣播功能
該功能利用網(wǎng)絡通信相關技術,實現(xiàn)服務端與配置文件中所有客戶端之間的廣播通信。服務端封裝本地文件到達的消息形成數(shù)據(jù)報文。接著,利用通信技術將報文廣播給每一個客戶端。
1.2.3客戶端解報功能
客戶端將服務端封裝廣播的報文按照既定的格式和對應的解碼規(guī)則進行解析,解析后的數(shù)據(jù)為客戶端提供調用數(shù)據(jù)的相關信息。
1.2.4客戶端定制功能
客戶端提供相應下載資料的選項,地市局用戶可根據(jù)自己需要定制需要推送的資料。客戶端將收到的消息根據(jù)用戶的選項進行過濾,符合規(guī)則的資料啟動下載機制進行下載。具體界面見圖3。
1.2.5客戶端下載功能
客戶端根據(jù)定制功能啟動相應的下載機制,從服務端通過HTTP協(xié)議下載資料并自動保存至設定的目錄,并將下載失敗的消息記錄插入用戶本地數(shù)據(jù)庫中。
圖4 客戶端自動接收界面
1.2.6客戶端補調功能
客戶端定時掃描本地數(shù)據(jù)庫中由于各種原因導致的下載失敗的消息記錄,根據(jù)下載路徑的拼裝規(guī)則,將相應字段拼裝成Web的下載路徑,進行數(shù)據(jù)補調。補調后的數(shù)據(jù)仍然存放于各種資料對應的目錄中。對于補調成功的數(shù)據(jù),客戶端自動從數(shù)據(jù)庫中刪除對應的記錄,實現(xiàn)用戶的零干涉和數(shù)據(jù)庫中消息記錄的自動維護管理。
2.1 服務端
2.1.1軟硬件環(huán)境
服務器操作系統(tǒng):Windows Server 2003/2008; Web服務器:IIS6.0;軟件開發(fā)環(huán)境:Microsoft Visual Studio 2008;開發(fā)語言:C#。
2.1.2功能要點與技術實現(xiàn)
2.1.2.1 配置文件解析
該模塊實現(xiàn)對配置文件的解析功能,將配置文件的內容按照規(guī)定的格式解碼后,提取相關的本地文件路徑信息和對端IP、端口等信息。實現(xiàn)該模塊的核心代碼如下:
…………
private string dataGet()
{
XmlDocument doc = new XmlDocument();
try
{
doc.Load("config.xml");
}
catch (Exception ex)
{
return "";
}
string JSON = DataGet.XmlToJSON(doc);
JSON = JSON.Replace(@"", @"\");
return JSON;
}
…………
2.1.2.2 文件監(jiān)聽
該模塊實現(xiàn)對本地文件的監(jiān)聽,提取相關文件信息,供服務端推送給客戶端使用。實現(xiàn)該模塊的核心代碼如下:
…………
private void fileSystemWatcher1_Created(object sender, FileSystemEventArgs e)
{
…………
string filepath = e.FullPath;
…………
ThreadWithState tws = new ThreadWithState(filepath, rc.IP, syspara.PUTConfig.WatchDIRParent.WatchDirChild.ElementAt
}
…………
2.1.2.3 建立與客戶端的通信
該模塊實現(xiàn)使用socket()來建立TCP連接,綁定對應的 IP和端口,連接建立后進入與服務端的通信狀態(tài)。實現(xiàn)該模塊的核心代碼如下:
…………
//指向遠程服務端節(jié)點
IPEndPoint ipep = new
IPEndPoint(IPAddress.Parse(remoteip_inner), 2005);
//創(chuàng)建套接字
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//連接到發(fā)送端
client.Connect(ipep);
//獲得客戶端節(jié)點對象
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
…………
2.1.2.4 報文封裝、發(fā)送
該模塊將監(jiān)聽到的文件到達的相關消息按照約定好的格式封裝后,發(fā)送給各個客戶端。實現(xiàn)該模塊的核心代碼如下:
…………
string file_createtime = EzoneFile.CreationTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
string file_writetime = EzoneFile.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
string time_str = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
//發(fā)送[落地信息中心時間和信息中心監(jiān)聽到文件的時間]到客戶端
CommonModule.EzoneModule.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file_createtime + " | " + file_writetime + " | " + time_str));
string filename_temp = EzoneFile.FullName.Substring(start_index, EzoneFile.FullName.Length - start_index);
string filename2 = localip_inner;
//發(fā)送[文件名]到客戶端
CommonModule.EzoneModule.SendVarData(client,System.Text.Encoding.Unicode.GetBytes(filename_temp));
//發(fā)送[文件頭]到客戶端
CommonModule.EzoneModule.SendVarData(client,System.Text.Encoding.Unicode.GetBytes(filename2));
//發(fā)送[包的大小]到客戶端
CommonModule.EzoneModule.SendVarData(client,System.Text.Encoding.Unicode.GetBytes(EzoneFile.Length.ToString()));
…………
2.2 客戶端
2.2.1軟硬件環(huán)境
服務器操作系統(tǒng):Windows Server 2003/2008;軟件開發(fā)環(huán)境:Microsoft Visual Studio 2008;數(shù)據(jù)庫:Microsoft access2003;開發(fā)語言:C#。
2.2.2功能要點與技術實現(xiàn)
2.2.2.1 客戶端與服務端通信功能
該模塊實現(xiàn)客戶端與服務端建立通信連接,并長時間監(jiān)聽服務端發(fā)送的消息,當有消息到達時進行響應處理。實現(xiàn)該模塊的核心代碼如下:
…………
//創(chuàng)建一個網(wǎng)絡端點
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, int.Parse("2005"));
//創(chuàng)建一個套接字
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//綁定套接字到端口
server.Bind(ipep);
try
{
while (true)
{
InitConfig();
//開始偵聽(并堵塞該線程)
server.Listen(100);
//確認連接
Socket client = server.Accept();
//獲得客戶端節(jié)點對象
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
…………
2.2.2.2解報功能
該模塊主要實現(xiàn)將收到的服務端發(fā)送的消息按約定格式進行解報,解報后得到的信息供后面的數(shù)據(jù)過濾、下載使用。實現(xiàn)該模塊的核心代碼如下:
…………
//獲得[文件落地信息中心時間]
string xxzx_filetime = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));
//獲得[文件名]
string SendFileName = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));
//MessageBox.Show("文件名" + SendFileName);
//獲得[文件名]
string FileName_download = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client)) + SendFileName.Replace("\", "/");
…………
2.2.2.3 數(shù)據(jù)定制功能
該模塊實現(xiàn)數(shù)據(jù)的定制,用戶可根據(jù)自己的需要在配置界面選定需要下載的數(shù)據(jù)選項,客戶端根據(jù)用戶的配置信息過濾掉用戶不需要的數(shù)據(jù)。該模塊的具體實現(xiàn)代碼如下:
…………
//對文件名進行過濾處理
result_station = station_pattern.Split(stringSeparators, StringSplitOptions.None);
result_product = rad_pattern.Split(stringSeparators, StringSplitOptions.None);
result_other = other_pattern.Split(stringSeparators, StringSplitOptions.None);
for (int i = 0; i < result_station.Length; i++)
if (!result_station[i].Equals(""))
{
if (SendFileName.Contains(result_station[i]))
{
flag_station = true;
}
}
for (int i = 0; i < result_product.Length; i++)
if (!result_product[i].Equals(""))
{
if (SendFileName.Contains("\" + result_product[i]))//目錄名+/進行區(qū)分
{
flag_rad = true;
}
}
…………
2.2.2.4 客戶端下載功能
該模塊實現(xiàn)用戶定制好的數(shù)據(jù)在客戶端收到消息后自動啟動下載功能,并按指定好的目錄規(guī)則進行存放。該模塊的具體實現(xiàn)代碼如下:
…………
WebClient client = new WebClient();
string pathURL = url;
int n = url.LastIndexOf("/");
string fileName = pathURL.Substring(n + 1, pathURL.Length - n - 1);
string pathDest = descpath;
bool flag_error = true;
int count = 0;
{
try
{
WebRequest myre = WebRequest.Create(pathURL);
test_str = pathURL;
}
catch (WebException exp)
{
ex_error = exp.ToString();
}
try
{
client.DownloadFile(pathURL, pathDest);
flag_error = false;//下載成功,結束下載。
string info = System.DateTime.Now.ToString() + pathDest + "文件下載成功! ";
}
catch (WebException ex)
{
string info = System.DateTime.Now.ToString() + pathDest + "文件下載失??! ";
ex_error = ex.ToString();
}
…………
2.2.2.5 客戶端補調功能
該模塊實現(xiàn)定時掃描數(shù)據(jù)庫,將下載失敗的記錄重新進行下載,下載成功后從數(shù)據(jù)庫中刪除該記錄。具體實現(xiàn)代碼如下:
…………
private void Redown()
{
//數(shù)據(jù)庫里面flag標記為1的需補調,補調成功后將該字段置為0;
try
{
//Flag標志為1需補調,為0已補調過。
string querystring = "select path,url,shijian from message where flag='1'";
DataSet dt = DbSQL.Query(querystring);
/////////開始補調
richTextBox1.AppendText("*************" + System.DateTime.Now.ToString() + "開始補調數(shù)據(jù)******************** ");
//此處開始下載。。。。。。
…………
ThreadWithState_download t_down = new ThreadWithState_download(dr[1].ToString(), dr[0].ToString(), true);
//開啟文件傳輸子線程
Thread TempThread3 = new Thread(new ThreadStart(t_down.StartDownload));
TempThread3.Start();
TempThread3.Join();
if (!t_down.ex_error.Equals(""))
{
richTextBox1.AppendText(System.DateTime.Now.ToString() + dr[0] + "文件補調失敗?。。。?! ");
//超過60分鐘無法補調的直接刪除
if (DateTime.Compare(Convert.ToDateTime(dr[2].ToString()).AddMinutes(60), DateTime.Now) < 0)
{
try
{
//Flag標志為1需補調,為0已補調過。
string updatestring = "update message set flag='0' where path='" + dr[0] + "'";
DbSQL.ExecuteSql(updatestring);
}
…………
else
{
richTextBox1.AppendText(System.DateTime.Now.ToString() + dr[0] + "文件補調成功! ");
//文件補調成功,將flag字段置為0
try
{
//Flag標志為1需補調,為0已補調過。
string updatestring = "update message set flag='0' where path='" + dr[0] + "'";
DbSQL.ExecuteSql(updatestring);
}
…………
本文依據(jù)現(xiàn)有業(yè)務流程和網(wǎng)絡資源,綜合運用網(wǎng)絡通信技術、數(shù)據(jù)庫技術、數(shù)據(jù)交換技術、Web技術和軟件設計開發(fā)等相關技術,設計并實現(xiàn)了基于文件到達消息的監(jiān)聽和廣播機制的實時資料推送軟件來實現(xiàn)省與地市、縣市之間資料的快速共享,解決了傳統(tǒng)方式共享資料不穩(wěn)定的問題,有效緩解了采用遍歷目錄的方式給服務器帶來的壓力。軟件實現(xiàn)過程中,采用完整的技術解決方案,妥善解決資料傳輸共享過程中可能出現(xiàn)的問題。另外,采用補調、數(shù)據(jù)庫自動維護等技術,實現(xiàn)用戶使用、維護簡單方便,實際業(yè)務運行證明該系統(tǒng)共享資料快速、穩(wěn)定。
[1] 鄧莉,王國復,孫超, 等.基本氣象資料共享系統(tǒng)建設[J]. 應用氣象學報, 2004, 15(B12):33-38.
[2] 李新慶,單新蘭,岳勇. 寧夏氣象數(shù)據(jù)共享查詢系統(tǒng)的設計與實現(xiàn)[J].重慶工商大學學報(自然科學版), 2015,32(3):55-59.
[3]王甫棣,王鵬,何恒宏.基于對等網(wǎng)絡技術的氣象數(shù)據(jù)共享服務應用[J]. 氣象科技, 2014,42(4):624-628.
[4] 李光明.應用Socket實現(xiàn)網(wǎng)絡通信[J]. 煤炭技術, 2012,31(8):88-90.
[5] 楊燕軍,馬鵬輝,張劍.基于Web服務的氣象信息共享方法[J]. 氣象水文海洋儀器, 2014,31(1):12-14.
[6] 康晉閩,楊賢棟.多策略快速下載的數(shù)據(jù)共享平臺的設計與實現(xiàn)[J]. 數(shù)字技術與應用, 2014(1):139.