2016-05-24 8 views
2

をこのYoutube videoに記載されているように、SseEmitterを使用して実装しようとしています。HTML5複数のリクエストを送信するEventSource

私はイベントストリームを開始し、サーバー送信イベントからデータを受け取ることができます。

しかし、複数のEventStreamタイプのリクエストがクライアントから送信され、サーバーに到着することがわかりました。私がそれを理解する方法、EventSourceは、HTTP要求を1つ送信してから、どのサーバーがクライアントにイベントを送信するかによってサーバーからhalf duplex接続を維持する必要があります。

なぜ定期的にリクエストを送信するのですか?半二重接続の代わりにポーリングが好きですか?

私が使用しているコードはベローです。

Serverコード

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.RestController; 
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; 
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter.SseEventBuilder; 

@RestController 
public class TestService { 
    private List<SseEmitter> subscriberList = Collections.synchronizedList(new ArrayList<>()); 

    @RequestMapping("inbox") 
    public SseEmitter inbox() { 
     SseEmitter subscriber = new SseEmitter(); 
     subscriberList.add(subscriber); 

     subscriber.onCompletion(() -> { 
      subscriberList.remove(subscriber); 
      System.out.println("Removed the completed event emitter"); 
     }); 

     System.out.println("Subscriber arrived"); 
     return subscriber; 
    } 

    @RequestMapping("message") 
    public String message(@RequestParam("message") String message) { 
     System.out.println("SubscriberList size " + subscriberList.size()); 
     for(SseEmitter subscriber : subscriberList) { 
      try { 
       SseEventBuilder eventBuilder = SseEmitter.event().name("group1").data(message); 
       subscriber.send(eventBuilder); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     }; 
     return message; 
    } 
} 

クライアントコード

$(function() { 
    console.log("Started"); 
    var eventSource = new EventSource("/inbox"); 
    eventSource.addEventListener('error', function(e) { 
     if (e.currentTarget.readyState == EventSource.CLOSED) { 
      console.log("Connection is closed") 
     } else { 
     source.close(); 
     console.log("Closing connection"); 
     } 
    }); 
    eventSource.addEventListener("group1", function (event) { 
     console.log(event.data); 
     document.querySelector("body").innerHTML += "<div>" + event.data + "</div>"; 
    }); 
}); 

ベローはクロム

enter image description here

からクライアントネットワーク]タブのスクリーンショットです

ここでは、サーバー側のログ

Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 

答えて

2

は、ここでの問題ではなく、それを開いたままにしながら、その作業を行うので、サーバーが突然接続を閉じることにあるのです。この問題が発生すると、クライアントは接続を開き、Server Sent Eventsのストリーミングを開始する要求を再送信します。その後、サーバーは接続を何度も閉じて、無限ループにつながります。

これを確認する1つの方法は、ブラウザの待機時間を長くするために、retryフィールドを設定することです(デフォルトは約2〜3秒です)。別の方法は、要求が到着した直後にサーバー側にwhile (true) {}を置くことです。

またSSEについてはthis postをご覧ください。

+0

ありがとう、私は閉じたソケットのネットワークを監視し、私の所見を共有しようとします。 – 11thdimension

関連する問題