4

プログラムを書いています。私のプログラムは、HTTP プロトコルを介してサーバーからデータを受け取ります。データはサーバーによって私のプログラムにプッシュされます。WebRequest を使用しようとしましたが、1 つのセッションのデータしか受信しませんでした。サーバーから継続的にデータを受信するために、接続を維持するにはどうすればよいですか。

以下は SDK ドキュメントです。

GUESTまたはADMINの権限で、一連のライブ画像を取得できます(サーバープッシュ)。画像を取得するには、図に示すように「/liveimg.cgi?serverpush=1」にリクエストを送信します。2-1-1.
カメラはクライアントから上記のリクエストを受け取ると、図のようにリターンを返します。2-2.
各 JPEG データは「--myboundary」で区切られ、「--myboundary」の後に「Content-Type」ヘッダーとして「image/jpeg」が返されます。「Content-Length」ヘッダーの場合、--myboundary データのバイト数を返します (「--myboundary」、各ヘッダー、区切り文字として \r\n を除く)。「Content-Length」ヘッダーと「\r\n」(デリミタ)の後に、実際のデータが送信されます。
このデータ送信は、クライアントが接続を停止する (切断する) か、何らかのネットワーク エラーが発生するまで続きます。

int レン; 文字列 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);
4

5 に答える 5

2

StreamHubプッシュサーバーを確認することをお勧めします。これは人気のあるCometサーバーであり、C#(またはVB / C ++)でリアルタイムのプッシュ更新を受信できる.NETクライアントSDKを備えています。

于 2009-09-25T21:52:50.560 に答える
2

サーバーがサポートしている場合は、HTTP 接続を長時間開いたままにしておくことができます。(すでに述べたように、これにより、サポートできる同時ユーザー数が大幅に制限されます。)

サーバーは Response.Buffer=false に設定し、ScriptTimeout を拡張する必要があります (サーバー側で ASP.NET を使用していると想定しています)。これを行うと、ページは、処理が完了するまで、必要に応じて Response.Write データを送信し続けることができます。

クライアントは、完全な応答をブロックするのではなく、接続が完了する前に着信応答を処理する必要があります。

于 2009-06-16T16:58:59.753 に答える
1

IPカメラからCookieを取得し、そのCookieを次のHttpWebRequestのヘッダーに含める必要があります。それ以外の場合は、常に「index.html」にリダイレクトしようとします。
これがあなたがそれをする方法です...

BitmapObjectは、Jpeg画像、現在の日付、および最終的なエラーテキストのコンテナとして機能するクラスです。接続が確立されると、200ミリ秒ごとに画像がプールされます。「serverpush」を介して取得された連続画像ストリームにも同じことが当てはまります。

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);
}
于 2011-05-30T06:26:21.717 に答える
1

私があなたを正しく理解している場合、サーバーは、クライアントの外部にあるクライアントにデータを送信して、要求/応答を行うことにより、何らかのイベントに応答します。これは正しいです?その場合、クライアントの数が非常に少ない場合を除いて、接続を開いたままにしておくことはお勧めしません。使用できる接続の数は限られているため、開いたままにしておくとすぐに例外が発生する可能性があります。

おそらく最も簡単な解決策は、クライアントに新しいデータを定期的にポーリングさせることです。これにより、単純なサーバーを使用できるようになり、クライアントでスレッドをコーディングして、1分または30秒ごとに1回、または最適な期間が何であれ、変更​​または新しい作業を要求するだけで済みます.

クライアントがポーリングせずに、サーバーが積極的にクライアントに通知するようにしたい場合は、単純な Web サーバー以外の何かを行う必要があります。また、着信要求を受け入れるようにクライアントをコーディングおよび構成する必要があります。クライアントがファイアウォールなどの背後で実行されている場合、これは難しい場合があります。この方法を使用する場合は、サーバーとクライアントを適切に構成できるため、おそらく WCF が最適です。

于 2009-06-16T16:57:28.523 に答える
0

標準の Web サーバーを使用している場合、何もプッシュすることはありません。代わりに、クライアントが定期的にプルする必要があります。

サーバープッシュデータを実際に取得するには、そのようなサーバーを自分で構築する必要があります。

于 2009-06-16T16:52:39.557 に答える