于文學(xué),張 鵬,畢聰瑞,陳紹飛
(中機(jī)試驗(yàn)裝備股份有限公司,吉林 長春 130103)
自動校直機(jī)現(xiàn)已成為工廠中不可或缺的智能裝備,代替人工操作液壓機(jī)等設(shè)備完成校直工序,降低人工勞動成本及時間成本,實(shí)現(xiàn)自動校正,使產(chǎn)品能夠滿足使用要求,極大地提高產(chǎn)品的利用率。隨著“數(shù)字化工廠”概念的誕生,工廠中的加工產(chǎn)品各工藝數(shù)據(jù)追溯顯得尤為重要,自動校直機(jī)同樣面臨著校正數(shù)據(jù)及設(shè)備運(yùn)行狀態(tài)實(shí)時傳輸?shù)膯栴}。
目前,工廠MES系統(tǒng)數(shù)據(jù)采集方式可分為以下三類:直接聯(lián)網(wǎng)通信進(jìn)行數(shù)據(jù)交互、通過工業(yè)網(wǎng)關(guān)通信進(jìn)行數(shù)據(jù)交互、遠(yuǎn)程IO模塊進(jìn)行數(shù)據(jù)交互。直接聯(lián)網(wǎng)通信適用于生產(chǎn)設(shè)備具備以太網(wǎng)通信網(wǎng)口,直接與局域網(wǎng)連接進(jìn)行數(shù)據(jù)傳輸。工業(yè)網(wǎng)關(guān)通信適用于生產(chǎn)設(shè)備不具備以太網(wǎng)通信網(wǎng)口硬件條件,通過PLC模塊進(jìn)行數(shù)據(jù)采集。當(dāng)生產(chǎn)設(shè)備既不具備以太網(wǎng)通信網(wǎng)口,也沒有使用PLC模塊,可增加遠(yuǎn)程IO模塊進(jìn)行數(shù)據(jù)采集。
基于HTTP協(xié)議進(jìn)行數(shù)據(jù)傳輸屬于直接聯(lián)網(wǎng)通信的一種主流方式。HTTP協(xié)議具有簡單快速、靈活、可擴(kuò)展性強(qiáng)的特點(diǎn),適用于工廠內(nèi)MES數(shù)據(jù)交互的應(yīng)用場景。因此,本文介紹了一種基于HTTP協(xié)議進(jìn)行數(shù)據(jù)傳輸?shù)姆椒?,與自動校直機(jī)上位機(jī)程序相融合,能夠快速地完成數(shù)據(jù)信息交互流程。
HTTP協(xié)議中文名為超文本傳輸協(xié)議,是一個基于請求與響應(yīng)模式的、無狀態(tài)的、應(yīng)用層的協(xié)議,以TCP協(xié)議為基礎(chǔ)進(jìn)行數(shù)據(jù)傳輸[1,2]。
HTTP服務(wù)端啟動服務(wù)并偵聽HTTP客戶端請求,客戶端封裝請求頭、請求體后發(fā)出請求。服務(wù)端偵聽到客戶端請求后進(jìn)行解析并處理,封裝響應(yīng)頭、響應(yīng)體,返回響應(yīng)消息,完成一次客戶端與服務(wù)端信息交互流程。HTTP協(xié)議工作流程如圖1所示。
圖1 HTTP協(xié)議工作流程
(1)GET方法。獲取服務(wù)器上的某一特定資源,請求的數(shù)據(jù)信息附加在服務(wù)器接口路徑之后,以“?”分割URL和傳輸數(shù)據(jù),多個參數(shù)用“&”連接[3]。傳輸?shù)臄?shù)據(jù)大小受URL長度限制,少量的數(shù)據(jù)傳輸適宜采用GET方法進(jìn)行資源請求。
(2)POST方法。向服務(wù)器提交資源讓服務(wù)器處理,比如提交表達(dá)、上傳文件等。請求的數(shù)據(jù)放置在HTTP請求包的包體中,理論上傳輸?shù)臄?shù)據(jù)大小不受限制。
(3)PUT方法。向服務(wù)器發(fā)送請求。如果URL不存在,服務(wù)器根據(jù)請求創(chuàng)建資源;如果URL存在,根據(jù)請求修改URL資源[4]。
(4)DELETE方法。請求服務(wù)器刪除某一特定資源。
(1)安全性
HTTP協(xié)議安全性較差。HTTP協(xié)議屬于明文傳輸協(xié)議,數(shù)據(jù)交互過程沒有進(jìn)行任何加密及通信認(rèn)證。GET方法更是將請求的數(shù)據(jù)信息完全顯示在URL路徑之后,無需任何數(shù)據(jù)解析便可直接獲取請求數(shù)據(jù)內(nèi)容。若對數(shù)據(jù)安全性要求較高,不建議使用HTTP協(xié)議,可采用HTTPS協(xié)議實(shí)現(xiàn)。
(2)可靠性
HTTP協(xié)議基于TCP協(xié)議進(jìn)行數(shù)據(jù)傳輸。TCP協(xié)議是一個連接傳輸協(xié)議,因此HTTP協(xié)議數(shù)據(jù)傳輸可靠性較高。
(3)靈活、擴(kuò)展性
HTTP協(xié)議對于報文沒有太多限制,可根據(jù)實(shí)際情況靈活擴(kuò)展,程序改動量較小。
自動校直機(jī)傳輸?shù)臄?shù)據(jù)主要分以下兩部分:一部分為設(shè)備實(shí)時狀態(tài)數(shù)據(jù),另一部分為產(chǎn)品加工數(shù)據(jù)。保持著程序高內(nèi)聚、低耦合的設(shè)計思想,將上位機(jī)程序設(shè)計成既是服務(wù)端,又是客戶端。服務(wù)端負(fù)責(zé)監(jiān)聽MES系統(tǒng)請求,將設(shè)備實(shí)時工作狀態(tài)數(shù)據(jù)進(jìn)行封裝,作為請求響應(yīng)返回給MES系統(tǒng)??蛻舳送ㄟ^POST方法向MES系統(tǒng)服務(wù)器發(fā)送產(chǎn)品加工數(shù)據(jù),實(shí)現(xiàn)產(chǎn)品校直工藝數(shù)據(jù)的可追溯功能。根據(jù)上述設(shè)計思想,程序設(shè)計流程如圖2所示。
圖2 程序設(shè)計流程圖
上位機(jī)程序在.NET Framework 4.5框架上進(jìn)行開發(fā),工程項(xiàng)目引用System.Web.dll,并添加System.Net、System.Web命名空間。
(1)啟動服務(wù)端
通過以下方式啟動服務(wù)器:
//port為服務(wù)端偵聽端口
listener = new TcpListener(port);
listener.Start();
(2)解析客戶端請求并響應(yīng)
服務(wù)端調(diào)用AcceptTcpClient()偵聽客戶端請求。
public void process()
{
Task.Factory.StartNew(() =>
{
inputStream=
new BufferedStream(socket.GetStream());
outputStream = New StreamWriter
(new BufferedStream(socket.GetStream()));
try
{
parseRequest();
readHeaders();
if (http_method.Equals("GET"))
handleGETRequest();
else if (http_method.Equals("POST"))
handlePOSTRequest();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.ToString
());
writeFailure();
}
outputStream.Flush();
inputStream = null;
outputStream = null;
socket.Close();
});
}
上述程序Socket變量為AcceptTcpClient()的返回值,通過以上程序可完成客戶端請求方法及對數(shù)據(jù)進(jìn)行解析。
客戶端程序主要調(diào)用GET方法與POST方法進(jìn)行資源請求與發(fā)送。HttpWebRequest類屬性設(shè)置如下:
KeepAlive屬性:客戶端設(shè)置是否與服務(wù)端建立持續(xù)型連接,默認(rèn)值為true。
Method屬性:客戶端設(shè)置請求的方法,默認(rèn)值為GET。
ContentType屬性:客戶端設(shè)置HTTP標(biāo)頭的數(shù)據(jù)格式,默認(rèn)值為null。
Timeout屬性:客戶端設(shè)置請求超時前等待的毫秒數(shù),默認(rèn)值為100s。
(1)GET方法程序
public static string Get(string Url)
{
HttpWebRequest getrequest = (HttpWebRequest)
WebRequest.Create(Url);
getrequest.Proxy = null;
getrequest.KeepAlive = false;
getrequest.Method = "GET";
getrequest.ContentType =
"application/json; charset=UTF-8";
getrequest.AutomaticDecompression = DecompressionMethods.GZip;
getrequest.Timeout = 2 * 1000;
HttpWebResponse getresponse =(HttpWebResponse)
getrequest.GetResponse();
Stream myResponseStream
getresponse.GetResponseStream();
StreamReader mygetStreamReader = new
StreamReader(myResponseStream, Encoding.UTF8);
string retgetString =
mygetStreamReader.ReadToEnd();
mygetStreamReader.Close();
myResponseStream.Close();
if (getresponse !=null)
getresponse.Close();
if (getrequest !=null)
getrequest.Abort();
return retgetString;
}
(2)POST方法程序
public static string Post(string Url, string Data, string Referer = null)
{
HttpWebRequest postrequest =
(HttpWebRequest)WebRequest.Create(Url);
postrequest.Method = "POST";
postrequest.Referer = Referer;
byte[] bytes = Encoding.UTF8.GetBytes(Data);
postrequest.ContentType =
"application/x-www-form-urlencoded";
postrequest.ContentLength = bytes.Length;
postrequest.Timeout = 2 * 1000;
Stream myResponseStream =
postrequest.GetRequestStream();
myResponseStream.Write(bytes, 0, bytes.Length);
HttpWebResponse postresponse =
(HttpWebResponse) postrequest.GetResponse();
StreamReader mypostStreamReader = new
StreamReader(postresponse.GetResponseStream(), Encoding.UTF8);
string retpostString =
mypostStreamReader.ReadToEnd();
mypostStreamReader.Close();
myResponseStream.Close();
if (postresponse != null)
postresponse.Close();
if (postrequest != null)
postrequest.Abort();
return retpostString;
}
(1)服務(wù)端調(diào)用AcceptTcpClient()會阻塞線程執(zhí)行,直至客戶端發(fā)起請求。可在調(diào)用AcceptTcpClient()前調(diào)用Pending()判斷當(dāng)前是否存在掛起的連接請求。若存在則調(diào)用AcceptTcpClient()獲取請求數(shù)據(jù),若不存在則等待下一次輪詢。具體代碼如下:
While(true)
{
if(tcpListener.Pending())
tcpListener.AcceptTcpClient();
}
(2)服務(wù)端處理連接請求時可能耗時較長,由于自動校直機(jī)各軸位置控制對實(shí)時性要求較高,本程序采用任務(wù)模式進(jìn)行數(shù)據(jù)處理,Action為連接請求處理函數(shù)Task.Factory.StartNew(()=>Action)。
本文詳細(xì)介紹了基于HTTP協(xié)議進(jìn)行數(shù)據(jù)傳輸?shù)某绦蛟O(shè)計與實(shí)例。上位機(jī)采用C#程序開發(fā),使用HTTP協(xié)議傳輸數(shù)據(jù)極大減少了復(fù)雜的通信協(xié)議開發(fā)流程,程序簡潔、可讀性高、可擴(kuò)展性強(qiáng),而且設(shè)計周期短,數(shù)據(jù)傳輸效率高。目前現(xiàn)場的應(yīng)用情況表明,系統(tǒng)穩(wěn)定可靠運(yùn)行,可以廣泛地應(yīng)用到其他設(shè)備上,為MES數(shù)據(jù)傳輸提供了一種新的可靠傳輸方式。