透過Ajax技術模擬Server push功能

本文探讨了在Goahead web服务器上实现WebPush技术的方法,包括C语言编写的CGI程序示例及其运行机制。此外,还介绍了通过Ajax技术模拟Server Push功能的应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嵌入式中一般是使用开源的Goahead webserver服务器,CGI也都是用C语言进行编写开发的。项目中想要在web上实现图片流的视频播放效果,考虑到两种方法,一种是浏览器端来进行图片的主动获取,一种是服务器端来进行图片的主动推送,即webpush技术。webpush技术显然更高效,但在Goahead上的实现过程中遇到了点问题。

下面是一个最简单的使用C语言编写的CGI来测试使用Goahead是否支持Webpush技术,以及运行的机制。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
         int ret,i;
 
 
         printf ( "HTTP/1.1 200\r\n" ); //http协议的头及push技术头
         printf ( "Content-type: multipart/x-mixed-replace;boundary=section\r\n\r\n" );
         printf ( "--section\r\n" ); //push内容的开始边界,服务器进行识别
         for (i = 0; i < 10000; i++)
         {
                 printf ( "Content-type: text/plain\r\n\r\n" ); //指定内容的类型
                 printf ( "i = %d\n" , i);
                 printf ( "--section\n" ); //下一次内容开始
                 fflush (stdout); //刷新内容到浏览器,这个很关键,否则浏览器会是一次性显示的效果
                 usleep(100000);
         }
       
         return 0;
}
上述示例在IE浏览器上无法正确运行实现webpush效果,在Chrome浏览器和Firefox浏览器上均能实现webpush效果,即间隔100ms更新i的值。也就是说Goahead webserver是支持webpush技术的。实现视频流就是将循环中的printf("i = %d\n", i);换成jpg的图片数据发送给浏览器,内容类型改成“image/jpeg"。

但是在测试的过程中遇到了两个主要的问题:

  1. 如果想要实现图片流的视频播放效果,cgi中就必须是while(1)的无限循环,直到浏览器关闭请求,之后服务器会关掉这个cgi。这样好像会影响其它cgi的执行,这个无限循环是否是必须的?
  2. cgi的输出,即stdout的文件缓存是追加式的,而不是覆盖式的,即fflush操作并没有情况到之前的文件内容,后面的内容是不断追加的。这样因为第一个中的无限循环就会造成内存溢出问题(Out of memory)。


透過Ajax技術模擬Server push功能
 
 
劉智漢
 

前言

 筆者有幸於多年前曾參與民航局台北航站的機房監控系統建置,除了相關軟硬體的建置外,當時最主要的需求是希望能在人員不進入機房的狀況下,透過網路得知各監控器的數據及遠端操控相關設備(由於時值web剛興起,相關網路監控設備尚不發達的90年代初期,要如何將監控設備產生的監控數據藉由網路呈現在web網頁上,這對當時的程式設計師而言,可說是一件困難重重的事)。

 當時所採用的作法是:寫一個專用web監控server(也可說是特定功能的web server),用以蒐集各項監控設備產出的資訊;再藉由特定格式傳送到瀏覽器(browser)端,透過javascript的解析將資訊呈現給終端使用者。使用者若要在瀏覽器畫面上進行電源開關或鏡頭移動等控制需求,亦是透過相同的方法,將特定格式的訊息傳回到web監控server,再由server對設備送出監控命令,以完成對設備的控制需求。

 由於這樣的做法需要browser每隔一段時間透過隱藏的框架(iframe)去跟server要資料,以取得監控資訊,以便局部更新網頁上的數據。以現今的技術眼光來看,如此的運作模式可說是一項非常簡陋的作法,但在當時已經是一套業界的模範系統。

 現今的網頁技術趨勢已漸漸朝向不重新讀取全部頁面,而改以局部更新網頁的技術發展。使用者不需重整整個頁面,只需針對有異動的部份作更新即可。如此,一來可有效減少網路傳輸量,二來使用者也不需一再重整頁面才能看到網頁的最新部分。此作法雖比傳統的網頁讀取模式進步,但仍需在固定週期對server發出讀取資料的要求,以獲得更新後的資訊;若可以在伺服器資料一發生更新,即對browser自動發出更新通知,便能讓browser做更有效的資料讀取。

 由於筆者在研究所時期研究的議題也是透過網路來讀取設備資訊,在網頁呈現時同樣也遇到上述的問題。當時的解決方法即是由隱藏的iframe在背後傳輸資料,透過javascript更新,以達到網頁不需重整即能更新頁面資訊的目的。雖然在1995年Netscape Navigator新增了"server push"功能,讓Server可以透過"multipart/x-mixed-replace"的方式將更新的資訊push到client端,但一直到2004年以"Gecko-based"為核心的瀏覽器(如firefox)才完整地支援此技術。藉由提供callback function及onreadystatechange來告知瀏覽器更新的資訊已經到達;唯此項技術只支援以"Gecko-based"為核心的瀏覽器。

Ajax提供新的解決方案

 近年來,由於資安的議題大受重視,使得透過隱藏的iframe傳輸資料的方式愈來愈不被瀏覽器所接受,間接地也讓上述的解決方法受到阻礙,形成client每向server要一次資料,就會彈跳出是否要允許瀏覽器在背後傳送資料的問題。但有些人是直接將允許iframe傳輸資料的功能直接關閉,因而導致網頁無法正常運作。此一問題直到Ajax的出現才得以解決。

 Ajax能讓瀏覽器透過XMLHttpRequest(XHR)的方式向server要資料,可用來取代iframe的功能;同時也提供了目前資料傳輸的狀態,讓使用者能夠透過這些狀態去撰寫對應的程式,因此非常適合用來模擬server-push。

 目前坊間已經有許多工具,可以將XHR的功能整合成一個javascript檔案供程式設計師直接使用。因此,在比較許多網路上流行的版本後,我們選取了prototype這個javascript套件來作為我們使用Ajax模擬server push的基本套件。

 有興趣的讀者可到http://www.prototypejs.org/網頁下載系統開發所需要的程式後,直接將下載的檔案解壓縮到程式開發的目錄,即可以開始撰寫程式。

程式範例

 舉例來說,若我們要透過網路監控某處的溫度,而又希望能夠在server監控到數據改變時能夠更動client端的數值時,這時候就可以透過prototype來協助建構網頁。首先,我們設計一個簡單顯示目前偵測到溫度值的網頁,如【圖1】:


圖1 監控網頁原始碼

 在瀏覽器所見到的畫面會顯示如【圖2】:


圖2 監控網頁

 當使用者按下【Start】按鍵後,系統才會開始執行讀取目前溫度計狀態的動作;而畫面會持續將系統偵測到的溫度數據持續顯示出來。此網頁中包含兩個 javascript檔案,即:prototype.js及my.js。其中,prototype.js主要提供一些包裝好的Ajax function,用於系統開發時簡化XHR的撰寫;my.js則是我們自己撰寫的程式內容,如【圖3】所示:


圖3 my.js 程式內容

 透過prototype.js所提供的Event.observe,在視窗載入資訊時按鍵按下(click),結合chkDerverData function執行函數去檢查Server目前的狀態,此時便進入了監控的迴圈。如果資料成功回傳到client端,即會根據傳回之數據進行判斷,並再進行server資料的檢查。若執行chkServerData成功,就會把回傳回來的數字寫入id為measureTxt的span中,以更新目前的偵測數值;而若執行失敗,則會將失敗訊息寫入id為ErrorTxt的span中。mydetect.php乃是偵測程式或是資料讀取程式,主要負責讀取偵測器的目前狀態並輸出給網頁。透過上述這套簡單的做法,便可成功地模擬出server-push,做出與以往需透過iframe來讀取資料的靜態網頁完全不同的互動網頁。

結語

 透過以上簡單的介紹及模擬,可以得知如何模擬server-push的互動功能。Server-push非常適合應用於系統執行完一件事之後,才通知使用者之應用上,這樣使用者可以不必一直重整網頁,也不會有因為系統執行太久,而被伺服器強制斷線的狀況發生。

參考資料


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值