簡體   English   中英

c#如何接收服務器推送數據?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM