2012-06-29 2 views
2

나는 기존 응용 프로그램을 업그레이드하고 새 버전에서 나는 OS 5을 필요로 - 이유 중 하나는 내가 모든 추가 할 필요없이 HTTP/HTTPS 우리의 서버를 통해 통신하는 ConnectionFactory를을 사용하고 싶다고했다 BES, BIS, Direct TCP, Wifi 등을 사용하기위한 URL 매개 변수.블랙 베리 ConnectionFactory를 타임 아웃

ConnectionFactory은 기본 유형을 통해 Google 서비스에 연결하는 가장 좋은 방법을 선택하도록 구성되었습니다.

내 연결 코드는 다음과 같습니다

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에 연결 매개 변수를 추가 할 때뿐만 아니라하지 작동합니다. 어떤 종류의 시간 초과 후 클라이언트가 연결을 닫는 것처럼 보이는 서버 로그에 오류가 발생합니다. 여기

는 일부 로그 예 :

는 IP Adresses는 RIM 네트워크 출신
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 

- 그래서 이들은 그 연결 상태 코드 400 (잘못된 요청을 받았습니다

BIS에서 오는 연결됩니다) 서버에서

줄 끝 부분에 큰 숫자가 있습니다 (예 : 10012644) 10012644 = 약 10 초

는 RIM 서버가 십초의 연결 시간 제한을 추가 마십시오 요청이 마이크로 서버에 처리 된 시간을 표시? 그것은 상당히 짧게 보인다!

문제는 재현하기 어렵습니다. 이전에 그런 경험을 한 사람이 있습니까?

+0

제한 시간은 2 분이었습니다. HttpConnection 만 사용합니다. BTW, 아마도 당신은'ConnectionFactory.setConnectionTimeout'을 호출하여 이것을 오버라이드하고 싶을 것입니다. 그리고 400 명 정도면 요청에 아무것도 잊었 니? (예 : SoapAction과 같은 HTTP 헤더). https에 대한 인증서가 있습니까? –

답변

1

이유를 찾았습니다. 문제는 아파치 모듈 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 인프라를 통해 요청 본문을 전송하는 것은 더 이상 필요하기 때문에 블랙 베리 클라이언트가 열심히 명중 WER 같아요.

값을 100 초로 설정하고 클라이언트가 계속 영향을 받는지 모니터링하십시오.