2

既存のアプリケーションをアップグレードし、新しいバージョンではOS 5が必要です-理由の1つは、 BES、BIS、Directを使用するためのすべてのURLパラメーターを追加せずに、HTTP/HTTPS経由でサーバーと通信するためにConnectionFactoryを使用したかったことです。 TCP、Wifiなど。

これで、 ConnectionFactoryは、優先タイプを介してサービスに接続するための最良の方法を選択するように構成されました。

私の接続コードは次のようになります:

ConnectionFactory connectionFactory = new ConnectionFactory();
BisBOptions bisOptions = new BisBOptions(BIS_SECRET);
connectionFactory.setTransportTypeOptions(TransportInfo.TRANSPORT_BIS_B, bisOptions);
connectionFactory.setConnectionMode(ConnectionFactory.ACCESS_READ_WRITE);
connectionFactory.setEndToEndDesired(true);
connectionFactory.setPreferredTransportTypes(new int[] { TransportInfo.TRANSPORT_BIS_B, TransportInfo.TRANSPORT_MDS,
TransportInfo.TRANSPORT_TCP_WIFI, TransportInfo.TRANSPORT_TCP_CELLULAR });
ConnectionDescriptor connectionDescriptor = connectionFactory.getConnection("https://myserver.com/serviceurl");
try {
  HttpConnection con = (HttpConnection) connectionDescriptor.getConnection();
  byte[] bytes = parameter.toString().getBytes(UTF_8);
  con.setRequestProperty(CONTENT_LENGTH, String.valueOf(bytes.length));
  os = con.openOutputStream();
  os.write(bytes);
  os.flush();
  int responseCode = con.getResponseCode();
  if (responseCode == 401) {
    throw new InvalidCredentialsException("Invalid credentials");
  } else if (responseCode != 200 && responseCode != 500) {
    EventLogger.logEvent(RTSID, ("Response code " + responseCode + " " + con
          .getResponseMessage()).getBytes(), EventLogger.ERROR);
    EventLogger.logEvent(RTSID, bytes, EventLogger.ERROR);
    throw new IOException("Invalid request");
  }
  is = con.openInputStream();
  if (is != null) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int c = 0;
    try {
      c = is.read();
    } catch (Exception ex) {
      c = -1;
    }
    while (c >= 0) {
      baos.write(c);
      try {
        c = is.read();
      } catch (Exception ex) {
        c = -1;
      }
    }
    String response = new String(baos.toByteArray(), UTF_8);
    try {
      JSONObject jsonObject;
      if (response.startsWith("[")) {
        jsonObject = new JSONObject();
        jsonObject.put(ARRAY, new JSONArray(response));
      } else {
        jsonObject = new JSONObject(response);
      }
      if (responseCode == 500) {
        throw new Exception(jsonObject.getString("message"));
      }
      return jsonObject;
    } catch (JSONException e) {
      EventLogger.logEvent(RTSID, ("Exception occured: " + e.toString()).getBytes(),
      EventLogger.ERROR);
    }
  }
} finally {
  if (is != null) {
    try {
      is.close();
    } catch (Exception e) {
    }
  }
  if (os != null) {
    try {
      os.close();
    } catch (Exception e) {
    }
  }
  if (con != null) {
    try {
      con.close();
    } catch (Exception e) {
    }
  }
}

私の問題は、接続パラメータをURLに手動で追加した場合と同じように機能しないことです。ある種のタイムアウト後にクライアントが接続を閉じたように見えるサーバーログにエラーが表示されます。

ログの例を次に示します。

93.186.30.120 - - [28/Jun/2012:15:50:08 +0200] "POST /service/methodX HTTP/1.1" 400 145 "-" "myapp VendorID/301" 10012567 
93.186.22.118 - - [28/Jun/2012:16:30:56 +0200] "POST /service/methodY HTTP/1.1" 400 145 "-" "myapp VendorID/137" 10012435
74.82.68.35 - - [28/Jun/2012:16:53:23 +0200] "POST /service/methodZ HTTP/1.1" 400 145 "-" "myapp BlackBerry9650/6.0.0.524 VendorID/105" 10012644

IPアドレスはRIMネットワークからのものです-したがって、これらはBISから来る接続です

これらの接続は、サーバーからステータスコード400(不正な要求)を取得しました

行末の大きな数字(例:10012644)は、サーバーでリクエストが処理された時間をマイクロ秒単位で示します。10012644=約10秒

RIMサーバーは10秒の接続タイムアウトを追加しますか?それはかなり短いようです!

問題を再現するのは難しいです-誰かが以前にそのようなことを経験したことがありますか?

4

1 に答える 1

1

私はその理由を見つけました。問題は、Apacheモジュールmod_reqtimeoutのデフォルト構成が原因で発生しました。

<IfModule reqtimeout_module>

# mod_reqtimeout limits the time waiting on the client to prevent an
# attacker from causing a denial of service by opening many connections
# but not sending requests. This file tries to give a sensible default
# configuration, but it may be necessary to tune the timeout values to
# the actual situation. Note that it is also possible to configure
# mod_reqtimeout per virtual host.


# Wait max 20 seconds for the first byte of the request line+headers
# From then, require a minimum data rate of 500 bytes/s, but don't
# wait longer than 40 seconds in total.
# Note: Lower timeouts may make sense on non-ssl virtual hosts but can
# cause problem with ssl enabled virtual hosts: This timeout includes
# the time a browser may need to fetch the CRL for the certificate. If
# the CRL server is not reachable, it may take more than 10 seconds
# until the browser gives up.
RequestReadTimeout header=20-40,minrate=500

# Wait max 10 seconds for the first byte of the request body (if any)
# From then, require a minimum data rate of 500 bytes/s
RequestReadTimeout body=10,minrate=500

</IfModule>

RIM BISインフラストラクチャを介したリクエスト本文の送信に時間がかかるため、BlackBerryクライアントはより大きな打撃を受けると思います。

値を100秒に設定し、クライアントが引き続き影響を受けるかどうかを監視します。

于 2012-07-02T13:38:36.263 に答える