2017-11-24 12 views
1

원격 장치의 메시지를 POST 메시지로 받아들이는 Django App이 있습니다.Django에서 Django 응답으로 Request.response를 다시 패키징하는 방법은 무엇입니까?

이것은 장고의 프레임 워크와 잘 맞습니다! 나는 일반적인 View 클래스 (django.views 가져 오기 뷰에서)를 사용하고 자신의 POST 함수를 정의했습니다.

그러나 원격 장치는 Django에서 생성 할 수없는 특수한 응답이 필요합니다 (아직). 그래서 요청 라이브러리를 사용하여 POST 메시지를 다시 작성하여 제조업체의 클라우드 서버로 보냅니다.

서버가 데이터를 처리하고 본문의 특수 메시지로 응답합니다. Idealy, 전체 HTML 응답 메시지는 원격 장치로 돌아 가야합니다. 유효한 회신을받지 못하면 메시지를 다시 보냅니다. 어느 쪽이 성가시겠습니까!

나는 인터넷 검색을 봤는데,하지만 문제가 하나하는 방법에 대한 명확한 그림 점점 데 :

의 (a) : 편집 한없이 Requests.response 객체와 장고에 다시 답글을.

(b) : Django 응답을 작성하여 다시 보내십시오.

사실 나는 (b)를하는 방법을 알고 있지만 그 일은 알고 있다고 생각합니다. 가능한 경우 오히려 (a) 할 것입니다.

미리 감사드립니다.

리치.

+1

이 특별한 회신은 어떻게 생겼습니까? 뭔가 표준인가? – Kanak

+1

Django에서'HttpResponse' 클래스를 사용하거나 하위 클래스를 사용하지 않을 이유가 없다고 생각합니다 : https://docs.djangoproject.com/en/1.11/ref/request-response/#httpresponse-objects –

+0

@ Kanak : 예, XML 문서입니다. –

답변

0

의견 및 질문에 감사드립니다.

야간 프로그래밍의 위험 : 뭔가 지나치게 생각하거나 명백한 것을 놓칠 수도 있습니다. 나는 아무런 변화/수정없이 request.response를 돌려 줄 방법을 찾는데 너무 집중했다. 나는 어떤 옵션 (b)이 무엇인지를 스케치하지 않았다.

글쎄, 그것의 아주 간단 밝혀 : 그 전송하기 전에 요청 객체와 원숭이 한 수 "의이"하나 "가 준비되어서"및 "보내기"를 사용할 수 있습니다

s = Session() 
# Populate POST to cloud with data from remote device request: 
req = Request('POST', url, data=data, headers=headers) 
prepped = req.prepare() 
timeout = 10 
retries = 3 
while retries > 0: 
    try: 
    logger.debug("POST data to remote host") 
    resp = s.send(prepped, timeout=timeout) 
    break 
    except: 
    logger.debug("remote host connection failed, retry") 
    retries -= 1 
    logger.debug("retries left: %d", retries) 
    time.sleep(.3) 
    if retries == 0: 
     pass # There isn't anything I can do if this fails repeatedly... 
# Build reply to remote device: 
r = HttpResponse(resp.content, 
       content_type = resp.headers['Content-Type'], 
       status = resp.status_code, 
       reason = resp.reason, 
       ) 
r['Server'] = resp.headers['Server'] 
r['Connection'] = resp.headers['Connection'] 
logger.debug("Returning Server response to remote device") 
return r 

세션을, 그리고 send를 다시 시도하십시오. 적어도 리팩터에서 제거 할 수 있다고 생각합니다. 이 과정을 더욱 단순하게 만듭니다.

여기 놀이에 3 HTTP 객체가 있습니다

  1. "REQ는"특별한 (암호화) 응답을 다시 얻기 위해 내가 클라우드 서버까지 보내는 POST입니다.

  2. "resp"는 클라우드 서버의 답장입니다. 본문 (.content)은 특별한 답장을 포함합니다.

  3. "r"은 내 볼에 데이터를 게시하여이 볼 롤링을 시작한 원격 장치로 다시 보내야하는 Django HTTP 응답입니다.

데이터 응답을 쉽게 채우고 헤더를 클라우드 서버가 반환하는 값으로 설정합니다.

원격 장치가 동일한 데이터를 두 번 POST하지 않기 때문에이 기능이 작동한다는 것을 알고 있습니다! 이 프로세스에서 실수가 발생하면 동일한 데이터를 반복해서 다시 보냅니다.Socket repeater 모듈에서 While/try 루프를 복사했습니다. 그게 정말 HTTP에 적용되는지 모르겠습니다. 나는 이것을 48 시간 이상 실제 하드웨어에서 테스트 해 왔으며 지금까지 실패한 적이 없다. 원격 장치와 클라우드 서버에 엄격한 제한이 있음을 알고 있으므로 시간 초과는 물음표입니다. 따라서 "repeater"에 오류가있는 경우 프로세스가 너무 오래 걸리면 다시 시도 할 수 없습니다. 현재 POST에서 폐기하거나 포기하는 것이 더 나을 수도 있습니다. 원격 장치가 다시 시도 할 때까지 기다립니다. 죄송합니다. 큰 소리로 리팩토링 ...