javascript - HTML5 EventSource sending multiple requests - Stack Overflow

I'm trying to implement Server Sent Events using Spring SseEmitter as described in this Youtube vi

I'm trying to implement Server Sent Events using Spring SseEmitter as described in this Youtube video.

I'm able to initiate the event stream and receive the data from the server sent event.

However, I can see multiple EventStream type requests fired from the client and arriving at the server. The way I understand it, EventSource should send a single HTTP request and then should maintain a half duplex connection from the server, using which server sends the events to the client.

Why is it then sending requests at regular interval ? Isn't it then like polling instead of a half duplex connection ?

Bellow is the code that I'm using.

Server code

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 pleted 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;
    }
}

Client code

$(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>";
    });
});

Bellow is the client network tab screenshot from chrome

Here's server side log

Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived

I'm trying to implement Server Sent Events using Spring SseEmitter as described in this Youtube video.

I'm able to initiate the event stream and receive the data from the server sent event.

However, I can see multiple EventStream type requests fired from the client and arriving at the server. The way I understand it, EventSource should send a single HTTP request and then should maintain a half duplex connection from the server, using which server sends the events to the client.

Why is it then sending requests at regular interval ? Isn't it then like polling instead of a half duplex connection ?

Bellow is the code that I'm using.

Server code

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 pleted 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;
    }
}

Client code

$(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>";
    });
});

Bellow is the client network tab screenshot from chrome

Here's server side log

Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Removed the pleted event emitter
Subscriber arrived
Share Improve this question asked May 24, 2016 at 2:09 11thdimension11thdimension 10.7k4 gold badges38 silver badges74 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

The problem here is that the server unexpectedly closes the connection, instead of doing its work while leaving it open. When this happnes, the client re-sends a request to open a connection and to start streaming Server Sent Events. The server then closes the connection again and again, leading to an infinate loop.

One way to make sure this is the case is to set the retry field in order to increase the browser's waiting time (the default is about 2-3 seconds). Another way is to have a while (true) {} on the server side, just after the request arrives.

Also take a look at this post about SSEs.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744747135a4591369.html

相关推荐

  • javascript - HTML5 EventSource sending multiple requests - Stack Overflow

    I'm trying to implement Server Sent Events using Spring SseEmitter as described in this Youtube vi

    3天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信