[英]how to receive server push data in c#?
我正在寫一個程序。 我的程序通過 HTTP 協議從服務器接收數據。 數據將由服務器推送到我的程序。 我嘗試使用 WebRequest,但只收到一個 session 的數據。 我怎樣才能保持連接活躍,從服務器接收數據 continuosly,任何幫助表示贊賞。
以下是SDK文檔:
在GUEST或ADMIN的授權下,可以獲得系列直播圖片(Server push)。 要獲取圖像,請將請求發送到“/liveimg.cgi?serverpush=1”,如圖所示。 2-1-1。
攝像頭收到客戶端的上述請求后,返回如圖所示。 2-2。
每個 JPEG 數據由“--myboundary”分隔,“image/jpeg”在“--myboundary”之后作為“Content-Type”header 返回。 對於“Content-Length”header,它返回 --myboundary 數據中的字節數(不包括“--myboundary”,每個 header,和 \r\n 作為分隔符)。 在“Content-Length”header 和“\r\n”(分隔符)之后,將發送實際數據。
這種數據傳輸會一直持續到客戶端停止連接(disconnect),或者出現一些網絡錯誤。
國際長度; string uri = @" http://192.168.0.2/liveimg.cgi?serverpush=1 ";
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Credentials = new NetworkCredential("admin", "admin");
req.KeepAlive = true;
string line = "";
HttpWebResponse reply = (HttpWebResponse)req.GetResponse();
Stream stream = reply.GetResponseStream();
System.Diagnostics.Debug.WriteLine(reply.ContentType);
StreamReader reader = new StreamReader(stream);
do
{
line = reader.ReadLine();
System.Diagnostics.Debug.WriteLine(line);
System.Threading.Thread.Sleep(300);
} while (line.Length>0);
如果服務器支持,您可以將 HTTP 連接保持打開較長時間。 (如前所述,這將顯着限制您可以支持的並發用戶數。)
服務器將需要設置 Response.Buffer=false,並具有擴展的 ScriptTimeout(我假設您在服務器端使用 ASP.NET)。 一旦你這樣做了,你的頁面就可以根據需要繼續發送 Response.Write 數據,直到完成它正在做的事情。
您的客戶端將需要在連接完成之前處理傳入的響應,而不是阻塞以等待完整的響應。
您可能想看看StreamHub 推送服務器- 它是一個流行的 Comet 服務器,並且有一個 .NET 客戶端 SDK,它允許您在 C#(或 VB/C++)中接收實時推送更新。
如果我對您的理解正確,您的服務器將通過向客戶端之外的客戶端發送數據來響應某些事件,從而發出請求/響應。 這個對嗎? 如果是這樣,我不建議嘗試保持連接打開,除非您的客戶端數量非常少——可用連接的數量有限,因此保持連接打開可能會很快導致異常。
可能最簡單的解決方案是讓客戶端定期輪詢新數據。 這將允許您使用一個簡單的服務器,並且您只需在客戶端上編寫一個線程,以每分鍾或三十秒或任何您的最佳時間段請求任何更改或新工作。
如果您真的想讓服務器主動通知客戶端,而無需他們進行輪詢,那么您將不得不做一些簡單的 web 服務器之外的事情——您還必須編寫代碼並配置客戶端以接受傳入的請求。 如果您的客戶端在防火牆等后面運行,這可能會很困難。 如果您使用 go 此路由,則 WCF 可能是您的最佳選擇,因為它將允許您適當地配置服務器和客戶端。
您需要從 IP cam 獲取一個 cookie,並將該 cookie 包含在下一個 HttpWebRequest 的 header 中。 否則它總是會嘗試將您重定向到“index.html”。
這是你如何做到的......
BitmapObject 是一個 class,用作 Jpeg 圖像、當前日期和最終錯誤文本的容器。 一旦建立連接,它將每 200 毫秒匯集一個圖像。 同樣應該適用於通過“serverpush”獲得的連續圖像stream。
public void Connect()
{
try
{
request = (HttpWebRequest)WebRequest.Create("Http://192.168.0.2/index.html");
request.Credentials = new NetworkCredential(UserName,Password);
request.Method = "GET";
response = (HttpWebResponse)request.GetResponse();
WebHeaderCollection headers = response.Headers;
Cookie = headers["Set-Cookie"];//get cookie
GetImage(null);
}
catch (Exception ex)
{
BitmapObject bitmap = new BitmapObject(Properties.Resources.Off,DateTime.Now);
bitmap.Error = ex.Message;
onImageReady(bitmap);
}
}
private Stream GetStream()
{
Stream s = null;
try
{
request = (HttpWebRequest)WebRequest.Create("http://192.168.0.2/liveimg.cgi");
if (!Anonimous)
request.Credentials = new NetworkCredential(UserName, Password);
request.Method = "GET";
request.KeepAlive = KeepAlive;
request.Headers.Add(HttpRequestHeader.Cookie, Cookie);
response = (HttpWebResponse)request.GetResponse();
s = response.GetResponseStream();
}
catch (Exception ex)
{
BitmapObject bitmap = new BitmapObject(Properties.Resources.Off,DateTime.Now);
bitmap.Error = ex.Message;
onImageReady(bitmap);
}
return s;
}
public void GetImage(Object o)
{
BitmapObject bitmap = null;
stream = GetStream();
DateTime CurrTime = DateTime.Now;
try
{
bitmap = new BitmapObject(new Bitmap(stream),CurrTime);
if (timer == null)//System.Threading.Timer
timer = new Timer(new TimerCallback(GetImage), null, 200, 200);
}
catch (Exception ex)
{
bitmap = new BitmapObject(Properties.Resources.Off, CurrTime);
bitmap.Error = ex.Message;
}
finally
{
stream.Flush();
stream.Close();
}
onImageReady(bitmap);
}
如果您使用的是標准的 web 服務器,它永遠不會向您推送任何內容 - 您的客戶端將不得不定期從它那里拉取。
要真正獲得服務器推送數據,您必須自己構建這樣的服務器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.