Server-sent event does not work with jersey SSE

走远了吗. 提交于 2019-11-30 17:31:16

问题


I am trying to use JavaScript SSE from Jersey. I have Following code in my resource. I am hosting on Java7 and Tomcat 7. I dont get any error. But I don't see data either on page.

I call /broadcast to post data. It does show message. But nothing comes on client. In Firefox, I do see /broadcast event fired multiple times.

This is reference I used. https://jersey.java.net/documentation/latest/sse.html

    package net.jigarshah.dse.tracker;

    import javax.inject.Singleton;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.GET;
    import javax.ws.rs.POST;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;

    import org.glassfish.jersey.media.sse.EventOutput;
    import org.glassfish.jersey.media.sse.OutboundEvent;
    import org.glassfish.jersey.media.sse.SseBroadcaster;
    import org.glassfish.jersey.media.sse.SseFeature;


@Singleton
@Path("broadcast")
public class SSEResource {
    private SseBroadcaster broadcaster = new SseBroadcaster();

    @POST
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.TEXT_PLAIN)    
    public String broadcastMessage(String message) {
        OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
        message = message + "\n\n";
        OutboundEvent event = eventBuilder.name("message")
            .mediaType(MediaType.TEXT_PLAIN_TYPE)
            .data(String.class, message)
            .build();

        broadcaster.broadcast(event);
        System.out.println("broadcasting listen [" +message+ "]");

        return "Message was '" + message + "' broadcast.";
    }

    @GET
    @Produces(SseFeature.SERVER_SENT_EVENTS)
    public EventOutput listenToBroadcast() {
        System.out.println("will listen");
        final EventOutput eventOutput = new EventOutput();
        this.broadcaster.add(eventOutput);
        return eventOutput;
    }
}

My Index.html code is as below.

<script type="text/javascript">
var url = "webapi/broadcast";
//var url="http://localhost:8080/trackapp/webapi/broadcast/listen";
var source=new EventSource(url);
source.onerror=function(event)
{
console.log("error [" + source.readyState + "]");
};

source.onopen = function(event){
    console.log("eventsource opened!");
    };

source.onmessage=function(event)
  {
    console.log(event.data);

  document.getElementById("result").innerHTML+=event.data + "<br>";
  };
</script>

回答1:


I had the same problem and solved it by not setting the name of the event (i don't know why but this seems to be the solution)... here is the code

OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();

//WARNING: IF I SET THE NAME OF THE EVENT IT DOES NOT WORK
//eventBuilder.name("message"); 

eventBuilder.mediaType(MediaType.APPLICATION_JSON_TYPE);
eventBuilder.data(EventData.class, data);
OutboundEvent event = eventBuilder.build();



回答2:


The OutboundEvent.Builder.name method sets the value of the SSE event field. Therefore, it is not treated as a message and cannot be listened using the .onmessage handler. The solution is simply using the addEventListener method to register the listener method.

This code should work with the Jersey sample above.

<script type="text/javascript">
    var url = "webapi/broadcast";
    var source=new EventSource(url);
    source.addEventListener(
        "message",
        function(event){
            console.log(event.data);
            document.getElementById("result").innerHTML+=event.data + "<br>"; },
        false);
</script>

I found this article to be useful to understand how the SSE works in the browser side: http://www.sitepoint.com/server-sent-events/.




回答3:


Here is an example which might be helpful to you: http://en.kodcu.com/2013/11/jaxrs-2-html-5-server-sent-events-on-glassfish-4/

And you may also refer to this page to see if your browser supports EventSource API http://www.eventsourcehq.com/browser-support




回答4:


I have to do the following to make it work with tomcat 7.0.69 and java 1.8, and jersey 2.22.2 Just sharing it if it comes to any use of any body.

  1. Add the following dependency in your Pom file :

      <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet-core</artifactId>
        <version>2.22.2</version>
      </dependency>
    
      <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.22.2</version>
      </dependency>
    <!-- If you use json -->
      <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-processing</artifactId>
        <version>2.22.2</version>
      </dependency>
    <dependency>
          <groupId>org.glassfish.jersey.containers</groupId>
          <!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core"  -->
          <artifactId>jersey-container-servlet</artifactId>
          <version>2.22.2</version>
        </dependency>
    
        <dependency>
          <groupId>org.glassfish.jersey.media</groupId>
          <artifactId>jersey-media-sse</artifactId>
          <version>2.22.2</version>
        </dependency>
    
  2. Needs to be servlet 3 so Heading of the web.xml should be like this : < ?xml version="1.0" encoding="UTF-8"? > < web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" >

  3. Jersey Servlet Container should be async-supported, so add it in the jersey servlet in the web.xml :

< async-supported>true< /async-supported >

  1. If you use any filter make sure it also async-supported :

    < async-supported>true< /async-supported>



来源:https://stackoverflow.com/questions/20702884/server-sent-event-does-not-work-with-jersey-sse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!