요청이 서버로 전송되고 응답을 기다리는 동안 인터넷 연결이 끊어지면 어떻게해야합니까?


14

서버에 엄청난 양의 데이터를 보내고 있습니다. 이제 데이터를 보내고 서버 응답을 기다리는 동안 갑자기 내 안드로이드 장치에서 인터넷 연결이 끊어집니다.
그래서 내가했던 일은 연결이 끊어 졌다는 경고 대화 상자를 표시하는 것이지만 서버 측에서 데이터가 이미 처리되어 URL 등의 어딘가에 업데이트되었습니다. 그러나 내 안드로이드 전화는 응답을 얻지 못했기 때문에 이것을 알지 못합니다. 그것을 해결하는 방법.
서버 쪽에서 할 수 있는지 아니면 안드로이드 자체에서 할 수 있습니까?
서버는 안드로이드 폰이 응답을 듣지 않을 것임을 어떻게 알 수 있습니까?
클라이언트-서버 통신 최적화 관점 일 수 있습니다.


우리는 얼마나 많은 데이터에 대해 이야기하고 있습니까? 기가 바이트?
Daniel Hollinrake

7-8MB 정도는 아니지만 서버 응답 시간이 너무 길고 전화에서 업로드 속도는 약 128KB / S입니다. 데이터 크기가 아니라 연결 문제에 대해 이야기하고 있습니다.
mayank_droid

답변:


15

이것은 비동기 트랜잭션에서 상당히 일반적인 문제이며 여러 부분으로 나뉩니다.

  1. 거래 요청이 성공적으로 접수되었음을 양측은 어떻게 알 수 있습니까?
  2. 고객이 제대로받지 못했다고 생각되는 거래 요청을 어떻게 다시 보내나요?
  3. 서버가 첫 번째 요청을 성공적으로 수신했을 때 서버는 클라이언트의 반복 요청을 어떻게 감지합니까?
  4. 고객은 거래 결과를 어디에서 얻을 수 있는지 어떻게 알 수 있습니까?

HTTP의 가장 큰 장점은 이러한 모든 문제를 쉽게 해결할 수 있다는 것입니다.

다음과 같은 URL 구조를 상상해보십시오.

POST http://my.server.com/application/engine/queue 
GET   http://my.server.com/application/engine/results?jobid=43425

HTTP post를 사용하여 고유 한 클라이언트 요청 ID를 사용하여 서버에 요청을 보내고 서버가 작업 ID로 응답하도록합니다. 클라이언트 관점에서이 응답이 발생하지 않으면 요청을 다시 보내야합니다. 클라이언트가 중복 된 요청을 보내는 경우를 대비하여 서버 관점에서 클라이언트 요청 ID를 몇 분 동안 캐시해야합니다. 중복 된 요청은 클라이언트에 동일한 작업 ID를 반환하여 간단히 처리됩니다.

클라이언트는 결과 URL에서 요청 결과를 가져옵니다. 이 호출은 결과를 얻기 위해 필요한만큼 자주 반복 될 수 있습니다. 결과가 사용 가능하기 전에 호출 된 경우 응답은 NO-CONTENT 응답 일 수 있으므로 클라이언트는 서버가 작업 ID를 인식하지만 아직 컨텐츠를 가지고 있지 않음을 인식합니다. 작업 ID가 인식되지 않으면 NOT-FOUND가 적절한 응답입니다.

결과적으로 클라이언트는 네트워크가 손실되고 복구 될 때 항상 합리적인 조치를 취할 수 있으며, 마찬가지로 서버는 항상 클라이언트의 요청을 현명하게 처리 할 수 ​​있습니다


3
즉, 트랜잭션 ID를 요청하는 짧은 요청을 한 다음 트랜잭션에 데이터를 추가하는 여러 요청 (여기서 전송을 더 작은 청크로 분할하여 부분 승인을 얻을 수 있음)과 마지막 "커밋"요청입니다. 그런 다음 완전히 비어있는 트랜잭션 (클라이언트가 ID를받지 못했을 가능성이 높음), 부분적으로 업로드 된 트랜잭션 및 결과 (클라이언트가 결과를받지 못한 경우 "커밋"요청을 다시 시도 할 수 있음)에 대해 서로 다른 시간 초과를 가질 수 있습니다.
Simon Richter

요청 전송 중에 연결이 끊어진 상황을 관리합니다. 요청 된 질문은 데이터를 보낸 후 요청이 완료되기 전에 연결이 끊어 졌다는 것입니다.
Michael Shaw

1
또한 처리됩니다. "커밋"트랜잭션은 작고 트랜잭션 ID를 사용하므로 데이터를 다시 전송하지 않고도 저렴하게 재발급 할 수 있으며 서버는 처리를 시작하거나 이전 호출의 결과를 반환 할 수 있습니다. 이것은 당신이 제안하는 것과 매우 유사합니다. 차이점은 작업 ID를 작성하기 위해 별도의 요청이 있으므로 추가 동기화 지점이 있으므로 클라이언트는 전체 요청을 다시 전송하지 않고 작업이 이미 존재하는지 알 수 있습니다.
Simon Richter

그래, 그 말이 맞아
Michael Shaw

이렇게하면 트랜잭션에 서버의 부분 데이터가 포함되어 있으면 클라이언트 가이 ID를 알고 트랜잭션을 완료하려고 시도하므로 부분 상태를 유지하고 전송을 중간에 재개하도록 제안하여 대역폭 요구 사항을 최소화하고 중복을 찾기 위해 요청 내용을 비교해야합니다.
Simon Richter

4

이것은 프로토콜 통신의 기본에 해당합니다. Android 클라이언트가 트랜잭션을 요청했으며 서버가 트랜잭션을 수행해야합니다. 트랜잭션이 Android 클라이언트 승인에 종속되는 경우 이는 통화 ACK / NAK 통신입니다.

ACK (승인) 및 NAK (음의 승인) 는 상대방에게 요청 결과를 알리는 데 사용됩니다.

당신이 요구하는 것은 클라이언트와 서버 간의 핸드 셰이크 교환 유형이며 , 기본 ACK / NAK 교환으로 수행 할 수 있습니다.

다음은 양방향 승인으로 파일을 업로드하는 Android의 예입니다.

Android -> upload files -> Server
Android <- ACK #id <- Server
Android -> ACK #id -> Server

위의 예 #id에서 거래에 대한 고유 식별자를 추가했습니다 . 서버는 파일을 수신하고 트랜잭션 레코드를 작성한 후 응답으로 다시 Android로 보내야합니다. 그런 다음 Android는 해당 거래에 대한 승인 (또는 거부에 대한 NAK)을 따라야합니다.

핸드 셰이 킹 중 Android 연결 끊기의 예는 다음과 같습니다.

Android -> upload files -> Server
Android <- ACK #id <- Server
/** no ACK response **/

위의 예제에서 서버는 업로드 된 파일을 수락하고 #idACK 응답을 다시 Android로 보냈지 만 Android는 ACK로 응답하지 않습니다. Android 기기가 핸드 쉐이킹을 완료하지 못했습니다. 서버가이를 처리하는 방법을 결정하는 것은 사용자의 책임입니다. 트랜잭션을 삭제하고 트랜잭션을 유지 한 후 나중에 Android 기기가 돌아 오기를 기다리거나 트랜잭션을 완료하십시오.

서버는 장치가 ACK로 응답하지 않았기 때문에 가정 할 수 있습니다. Android 기기가 내부 상태를 업데이트하지 않아 업로드에 성공했음을 나타냅니다. 트랜잭션을 버리고 나중에 장치가 트랜잭션을 반복하도록 허용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.