2013-03-06 1 views
0

저는 Pubnub를 사용하여 서버에서 클라이언트 (브라우저 페이지)로 실시간 메시지를 게시하고 있습니다. Pubnub를 사용할 때 메시지 크기 제약 조건을 준수해야합니다. 때로는 메시지를 조각 내고 조각으로 보내고 클라이언트 측에서 재구성해야합니다. Pubnub의 조언에 따라, Pubnub.publish() 함수가 너무 빨리 호출되지 않으면 (즉, 메시지 조각이 for 루프를 통해 단순히 펌핑되는 경우) 메시지의 각 청크를 전달할 수 있습니다.Ruby 콜백 함수가 다른 함수의 실행을 계속합니다.

Pubnub Ruby API는 Pubnub.publish()에 3 개의 필수 인수, 채널, 메시지 및 콜백 함수를 지정합니다. 아래 콜백 함수 Pubnub의 루비 예로부터이다 콜백 (안 발행의 "하이"메시지)에

@my_callback = lambda { |message| puts(message) } 
    pn.publish(:channel => :hello_world, 
     :message => "hi", 
     :callback => @my_callback) 

메시지 보내 같은 값으로 publish() 통화 상태 정보를 "포함 "와"message to large "(둘 다 고유 한 식별자가 동반 됨)

Pubnub 내부의 어딘가에서이 콜백에 .call()이 표시됩니다.이 프로세스에 들어가는 방법이 있는지 궁금합니다. 좀 더 자세하게 말하면, 세 개의 청크로 나눌 필요가있는 메시지가 있다고 가정하고, 청크 0을 보내고 싶습니다. 그리고 콜백에서 "보낸"상태를 받으면 청크 1을 보내고 싶습니다. 등 ...

나는 람다 기능과 범위를 잘 알고 아니에요, 이것은 내 첫 번째 시도였다

@my_callback = lambda { |message| 
          puts(message) 
          Rails.logger.debug("Setting pubnub_do_send to true from callback") 
          pubnub_do_send = true 
          } 

    pubnub_do_send = true 

    while !pubnub_message.nil? 
     if pubnub_do_send 

     #Send pubnub message 
     #Cut off first chunk of message (this is why I'm testing for nil) 
     #Set pubnub_do_send to false 

     Rails.logger.debug("Message #{message_id} chunk #{chunk_id} sent") 
     pubnub_do_send = false 
     end 
    end 

이는 완전한 실패의 결과 - 서버가 완전히 무한에 고정 점점 while 루프는 (추측해야만한다면) pubnub_do_send는 결코 true로 설정되지 않았기 때문입니다. 디버그 로그를 보면 첫 번째 메시지 print ("Message 1 chunk 0 sent")가 표시되지만 콜백 함수의 출력은 표시되지 않습니다. (아마도 무한 루프가 있기 때문에 아마도 그 자체가 발견되었습니다)

코드를 리팩터링하고 메시지를 채우고 배열에 먼저 저장하는 것이 좋습니다. 다음 간단하게 보낼 배열을 통해 반복하지만 솔루션을 멀리 떨어져 수없는 느낌, 난 그냥 너무 쉽게 람다 함수 및 콜백으로 편리 해요.

@my_callback = lambda { |message| 
          puts(message) 
          send_pubnub_message(message_id, chunk_id, chunk) 
          } 

    def send_pubnub_message(message_id, chunk_id, chunk) 
     #Send pubnub message 
     #Send message_id, next chunk_id, and next chunk to my_callback 
    end 

그러나 문제는 Pubnub.publish() 내게 직접 전화보다는 메시지에 대해 다시 약간의 상태를 얻을 때 Pubnub에 의해 호출됩니다 my_callback입니다 :

나는 같아야 솔루션 같은 느낌! (아직도 믹스의 메시지를 첨부 pubnub시키는 동안 나를 콜백에 MESSAGE_ID, CHUNK_ID, 및 청크를 삽입 할 수있는 방법이 있습니까? 즉,하지만 어쩌면 루비, 방법이 잘못 소리 ...)

감사에서 모든 도움을 위해 전진하십시오.

답변

1

콜백에서 메시지 청크 상태를 처리하려고해서는 안됩니다. 게시의 상태에 대해 알리는 단 하나의 책임이 있습니다. 그러나 메시지에 항목을 삽입 할 수 있습니다. 현재 상태를 알고있는 메시지 래퍼를 작성하여 람다에서 전송하므로 메시지를 추적 할 필요가 없습니다. 다음 코드를 테스트하지는 않았지만 여기에 내가 말하고자하는 내용의 예가 나와 있습니다.

class Message 
    attr_accessor :id, :message, :chunked_message, :chunk_id 
    def initialize(id, message) 
    @id, @message = id, message 
    chunk_message 
    end 
    def current_chunk 
    @chunked_message[@chunk_id] 
    end 
    def next_chunk 
    @chunk_id += 1 
    self 
    end 
    def more? 
    @chunked_message.length > chunk_id 
    end 
    private 
    def chunk_message 
    implement splitting message here 
    end 
end 


def send_pubnub_message(message) 
    pn.publish(:channel => :hello_world, 
    :message => message.current_chunk 
    :callback => lambda { |status| 
         puts(status) 
         case status[0] // 1 = success, 0 = fail 
         when 1 
          send_pubnub_message(message.next_chunk) if message.more? 
         when 0 
          handle_pubnub_error(status[1], message) 
         end 
         } 
end 
+0

좋은 솔루션처럼 보입니다. – MandM

+0

사실, 이것은 모델 방법처럼 보입니다. 맞습니까? 나는 컨트롤러에서 구현하려고했는데 아직도 할 수 있다고 생각합니다. Model 메서드를 만드는 것에 대한 당신의 생각이 궁금합니다. – MandM

+0

예, 모델의 위치가 정확합니다. 나는 당신의 아키텍쳐에 대해 모른다. 그래서 이것은 가장 간결한 방법이다. – quandrum

관련 문제