3

サーバーに接続し、(HttpURLConnection を使用して) 信号データを継続的に送信する Android アプリがあります。サーバー上では、スクリプト (シェルまたは Python、正確にはわかりません。私の側ではありません) が現在このストリームを処理し、受信データ パッケージごとに、このパッケージをサーブレット (Jetty 8 Web で実行) にポストするための curl 要求をセットアップします。容器)。データをサーブレットに直接接続してストリーミングする方法がわからないため、これは暫定的な解決策にすぎません。要件として、ファイアウォールによってブロックされないように、データ転送には HTTP プロトコルを使用する必要があります。

では、最初にサーブレットに接続してから、数分または数時間といった長時間にわたってデータをストリーミングすることは可能でしょうか? 同様の質問/解決策が見つからなかったのではないかと思っていました。つまり、これは特別なシナリオではありません。これは大きなファイルをサーブレットにアップロードする操作と同じですか?

サーブレットは実際には次のようになります。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
    System.out.println("StreamingServlet#doPost(): IN");
    BufferedReader reader = request.getReader();
    String data = "";

    while ((data = reader.readLine()) != null)
    {
        System.out.println("Data: " + data);
    }
    reader.close();

    System.out.println("StreamingServlet#doPost(): OUT");
}

Android アプリには、HttpURLConnection を使用する 3 つのメソッドがあります。

private Boolean connect(URL URLdest)
{
    try
    {
        connection = (HttpURLConnection) URLdest.openConnection();
        connection.setDoOutput(true);
        connection.setChunkedStreamingMode(0);
        oSWout = new OutputStreamWriter(connection.getOutputStream());
    }
    catch (IOException e)
    {
        return false;
    }
    return true;
}   

public void send(String packet)
{
    try
    {
        // TODO clOSWout.write and clOSWout.flush block may freeze if connection is lost. Somehow no exception is thrown and thread hangs instead.
        // It only occurs if the Server breaks the connection

        oSWout.write(packet);
        oSWout.flush();
    }
    catch (IOException e)
    {
        ...
    }
}

public void stopConnection()
{
    try
    {
        oSWout.close();
        connection.disconnect();
    }
    catch (IOException e)
    {
        ...
    }
}

最終的に私が期待しているのは、サーブレットに接続するときに「StreamingServlet#doPost(): IN」を出力し、次に、受信データパッケージごとにデータ文字列を出力し、接続を閉じるときに「StreamingServlet#」を出力することです。 doPost(): OUT」を実行し、最後にメソッドから戻ります。

しかし、私は何かが欠けていると思います。これは、Java EE では別の方法で行われます。知らない。

4

1 に答える 1

2

最後に、私は自分で問題を解決しました:

BufferedReader を使用すると、すべてのデータ パッケージが収集 (バッファリング) され、接続が閉じられたときに 1 つのパッケージとして読み取られて出力されます。そのため、ServletInputStream [HttpServletRequest#getInputStream() で取得] を使用し、read() メソッドを使用してデータ パッケージをバイト配列に読み込む必要がありました。これで、すべてが期待どおりに機能します。

しかし、ブロッキング操作を使用して doPost() メソッドに長い時間 (数分または数時間) とどまることが多かれ少なかれ典型的なシナリオなのか、それともサーバーが何らかの形ではるかに短い時間で応答することが期待されているのか疑問に思っています。 .

于 2012-07-16T13:03:36.880 に答える