Nginx & Comet: 저 지연 정보 푸 시

링크
 
서버 푸 시 (Server Push) 는 효율 적 이 고 지연 이 낮은 데이터 교환 방식 이다.만약 데이터 송신 단 과 수신 단 이 모두 인터넷 에서 공개 적 으로 볼 수 있다 면 Nginx & Comet: Low Latency Server Push 또는 PubSubHubbub 등 방법 으로 임 무 를 완성 할 수 있다.그러나 데이터 수신 자가 방화벽 안에 있 거나 내부 망 에 있 거나 브 라 우 저 (데이터 요청 만 외부 로 보 낼 수 있 고 들 어 오 는 데 이 터 를 처리 할 수 없다) 라면 서버 푸 시 를 실현 하 는 것 이 더욱 어렵다.모험 정신 이 있다 면 simpler Webhook 을 만 들 수 있 습 니 다.신뢰 할 수 있 는 해결 방안 을 찾는다 면 HTML 5 의 역방향 HTTP 서버 특성 을 기 다 려 야 할 지도 모른다.그러나 즉시 실현 할 수 있 는 해결 방안 이 필요 하 다 면 타협 하고 비동기 푸 시 모드 로 대체 할 수 있 습 니 다. WebSocket’s API 을 사용 할 수 있 고 역방향 Ajax, HTTP 서버 푸 시 또는 HTTP 흐름 이 라 고도 부 릅 니 다.
 
Comet 에서 나 쁘 지 않 은 기술 방향 을 제시 했다. 그것 은 바로 긴 연결 (Comet) 개념 이다. 클 라 이언 트 에서 시작 하여 데이터 가 나타 나 고 전송 (2006 년 알 렉 스 러 셀) 될 때 까지 연결 을 유지 하거나 영원히 연결 을 유지 하 며 이 를 통 해 데 이 터 를 클 라 이언 트 (long polling) 로 전송 하 는 것 이다.이 두 가지 방법의 장점 은 데이터 전송 이 매우 신속 하 다 는 것 이다.따라서 긴 연결 기술 은 채 팅 애플 리 케 이 션 (Facebook, Google, Meebo 등) 과 실시 간 트리거 를 실현 하 는 메커니즘 에 널리 사용 된다.
 
Nginx 를 긴 연결 서버 로 변환
 
긴 연결 서 비 스 를 실현 하 는 것 이 비교적 큰 문 제 는 특수 한 스텔스 수요 와 사건 구동 웹 서버 가 많은 긴 연결 을 효과적으로 처리 할 수 있 는 지 하 는 것 이다.streaming 서버 는 표준 응용 급 서버 의 좋 은 예 이다.또한 Leo Ponomarev 의 노력 에 감 사 드 립 니 다. 현재 Friendfeed 의 토 네 이도 플러그 인 으로 Nginx 서버 를 완전한 기능 의 긴 연결 서버 로 변신 시 킬 수 있 습 니 다.
 
사용자 정의 프레임 워 크 구 조 를 사용 합 니 다. Leo 의 플러그 인 은 두 개의 대외 인터페이스 만 제공 합 니 다. 하 나 는 구독 자 이 고 하 나 는 게시 자 입 니 다.클 라 이언 트 가 Nginx 서버 에 연결 하여 한 채널 에 대한 long - polling 긴 연결 을 만 들 고 데 이 터 를 기다 리 고 있 습 니 다.또한 게시 자 는 데 이 터 를 POST 방법 으로 Nginx 에 간단하게 제출 할 뿐 플러그 인 은 데 이 터 를 받 은 후에 기다 리 는 클 라 이언 트 에 게 하나씩 보 냅 니 다.이것 은 발표 자가 직접 데 이 터 를 전달 할 필요 가 없다 는 것 을 나타 낸다. 이것 은 단지 간단 한 사건 발생 기 일 뿐이다!
 
그리고 더욱 강력 한 기능 은 클 라 이언 트 와 발표 자 는 임의의 channel 을 만 들 수 있 고 플러그 인 은 메시지 큐 기능 을 제공 합 니 다. 즉, Nginx 서버 는 클 라 이언 트 가 끊 긴 상태 에서 메 시 지 를 임시로 저장 합 니 다.대기 열 메 시 지 는 시간, 대기 목록 길이, 메모리 제한 크기 에 따라 유효 하지 않 습 니 다.
 
Nginx 와 Ruby 설정 예
 
우선, 원본 코드 에서 Nginx 를 컴 파일 해 야 합 니 다.압축 해제 소스 패 키 지 는 GitHub 에서 플러그 인의 소스 코드 를 가 져 와 Nginx 의 소스 디 렉 터 리 에 넣 고 다음 매개 변 수 를 사용 하여 컴 파일 합 니 다 (. / configure – add - module = / path / to / plugin & make & make install).다음 단 계 는 nginx_http_push_module 파일 과 readme 파일 을 참고 하여 모든 매개 변수 옵션 을 알 아 보 세 요.다 중 클 라 이언 트 가 정 보 를 받 는 설정 예 는 다음 과 같 습 니 다.
 
협의
 
# internal publish endpoint (keep it private / protected)
#      (          )
location /publish {
  set $push_channel_id $arg_id;      #/?id=239aff3 or somesuch
  push_publisher;
 
  push_store_messages on;            # enable message queueing  #       
  push_message_timeout 2h;           # expire buffered messages after 2 hours # 2       
  push_max_message_buffer_length 10; # store 10 messages #   10   
  push_min_message_recipients 0;     # minimum recipients before purge #          
}
 
# public long-polling endpoint
#          
location /activity {
  push_subscriber;
 
  # how multiple listener requests to the same channel id are handled
  #   channel  id           
  # - last: only the most recent listener request is kept, 409 for others.
  # – last:               ,      409
  # - first: only the oldest listener request is kept, 409 for others.
  # – first:                 ,      409
  # - broadcast: any number of listener requests may be long-polling.
  # – broadcast:               
  push_subscriber_concurrency broadcast;
  set $push_channel_id $arg_id;
  default_type  text/plain;
}

 
Nginx 를 컴 파일 하고 시작 하면 우 리 는 간단 한 방송 장면 을 만 들 수 있 습 니 다. 하나의 데이터 전송 방송 자, 몇 개의 구독 정보 수신 자 를 통 해 우리 의 긴 연결 서버 를 테스트 할 수 있 습 니 다.
 
> nginx-push.conf
 
require 'rubygems'
require 'em-http'
 
def subscribe(opts)
  listener = EventMachine::HttpRequest.new('http://127.0.0.1/activity?id='+ opts[:channel]).get :head => opts[:head]
  listener.callback {
    # print recieved message, re-subscribe to channel with
    #         ,         
    # the last-modified header to avoid duplicate messages 
    #   header last-modified            
    puts "Listener recieved: " + listener.response + "\
" modified = listener.response_header['LAST_MODIFIED'] subscribe({:channel => opts[:channel], :head => {'If-Modified-Since' => modified}}) } end EventMachine.run { channel = "pub" # Publish new message every 5 seconds # 5 EM.add_periodic_timer(5) do time = Time.now publisher = EventMachine::HttpRequest.new('http://127.0.0.1/publish?id='+channel).post :body => "Hello @ #{time}" publisher.callback { puts "Published message @ #{time}" puts "Response code: " + publisher.response_header.status.to_s puts "Headers: " + publisher.response_header.inspect puts "Body: \
" + publisher.response puts "\
" } end # open two listeners (aka broadcast/pubsub distribution) # subscribe(:channel => channel) subscribe(:channel => channel) }

 
> comet-push-consume.rb Downloads: 270 File Size: 2.7 KB
 
위의 코드 에서 5 초 마다 데이터 게시 자가 Nginx 에 새로운 이 벤트 를 보 내 고 nginx 는 데 이 터 를 긴 연결 을 통 해 구독 하 는 두 클 라 이언 트 에 게 전달 합 니 다.클 라 이언 트 에 메 시 지 를 보 내 면 서버 가 연결 을 끊 고 클 라 이언 트 는 다음 데이터 가 오 기 를 즉시 다시 연결 하고 기다 릴 것 입 니 다.이렇게 해서 Nginx 가 클 라 이언 트 에 데 이 터 를 발표 하 는 실시 간 메시지 전송 체 제 를 실현 합 니 다!
 
Long Polling, Streaming, and Comet in Production
Leo 의 모듈 은 아직 개발 기간 이 므 로 안정 적 인 시간 이 필요 하지만 주목 해 야 할 프로젝트 입 니 다.최근 업데이트 계획 은 bug 복구 에 중점 을 두 고 있 습 니 다. 미래의 계획 에는 스 트림 을 추가 하 는 모드 가 있 습 니 다. 현재 데 이 터 를 가 져 올 때마다 다시 연결 해 야 하 는 상황 (long polling) 을 대체 하여 Nginx 는 연결 을 유지 하고 데 이 터 를 클 라 이언 트 에 실시 간 으로 전송 합 니 다.이 기능 을 가 진 후에 당신 은 자신의 정보 트리거 API (예 를 들 어 nginx-push.zip (Full Nginx Config + Ruby client)) 를 편리 하 게 배치 할 수 있 습 니 다.
 

좋은 웹페이지 즐겨찾기