0

i am trying to implement server side events. I have very simple resource exposed by a RESTful web service with Jersey/Grizzly. I try to broadcast the events with the SseBroadcaster. An event is created, whenever a data item comes in and is added to an internal list. A client should open a connection to the URL /events to receive the events.

@Path("sensordataelements")
public class SensorDataResource {

    private SseBroadcaster broadcaster = new SseBroadcaster();

    @GET
    @Path("events")
    @Produces(SseFeature.SERVER_SENT_EVENTS)
    public EventOutput getServerSentEvents() {
        final EventOutput eventOutput = new EventOutput();
        broadcaster.add(eventOutput);
        return eventOutput;
    }
    @POST
    @Path("/addraw")
    @Produces(MediaType.APPLICATION_JSON)
    public Response addRawSensorData(String elementBody) {
        ... data processing stuff ...
        cList.add(
                new SensorDataElement.SensorDataElementBuilder().id()
                .sensorReading(tmpValue)
                .build()
                );
        OutboundEvent evt = new OutboundEvent.Builder()
                .data(Float.class, Float.valueOf(tmpValue))
                .build();
        broadcaster.broadcast(evt);

        return Response.status(201).build();
    }
...

I tried to connect with

curl -v http://localhost:8080/sensordataapp/sensordataelements/events

The connection is fine, but i do not get any events. I looked at some examples, but got the impression that this should work. What did i miss?

Thanks!

Fluffy
  • 299
  • 1
  • 4
  • 21
  • Are you sure cURL supports SSE? Have you tried with a different client that supports SSE, like the Jersey client, or Javascript? Also after a client is connected, someone needs to send a post request to actually send a message to the subscribing client. – Paul Samsotha Dec 08 '16 at 15:23
  • Well, there are some examples showing curl beeing used. The POST method is called on a regular basis. So this sould be fine. Could there be a problem with the broadcaster class? – Fluffy Dec 12 '16 at 07:52
  • Make sure the resource class is a singleton. Otherwise a new one is created for each request, which means a new broadcaster is created for each request. Or if you want to keep the default behavior of a new resource created for each request. you should _inject_ a singleton instance of the broadcaster, instead of instantiating it yourself – Paul Samsotha Dec 12 '16 at 07:56
  • You can add `@Singleton` on top of the resource class. That will make it a singleton – Paul Samsotha Dec 12 '16 at 07:57
  • Declaring Singleton did the trick :) Thanks! Would you like to post this as an answer, so the question is marked as "solved"? Could you point me to a source where i can understand how to inject as a singleton? – Fluffy Dec 12 '16 at 08:17

1 Answers1

1

By default, a new instance of the resource class is created for each request. This means that a new broadcaster is created for each request, which isn't what you want. If you want to make the resource class a Singleton, you can simply annotate the class with @Singleton

@Singleton
@Path("sensordataelements")
public class SensorDataResource {
     ...
}

Now, only one instance of the resource class will be created for the entire application, and it will be shared for all requests.

The other option, is if you inject the broadcaster, instead of instantiating it yourself, you can inject it as a Singleton. Whether or not the resource class is a singleton or not, it will still get injected the same broadcaster instance. To do that, you can do something like the following in your ResourceConfig subclass

public class AppConfig extends ResourceConfig {
    public AppConfig() {
        register(new AbstractBinder() {
            @Override
            public void configure() {
                bind(new SseBroadcaster()).to(SseBroadcaster.class);
            }
        });
    }
}

Then in your resource class, just inject it

@Path("sensordataelements")
public class SensorDataResource {

    @Inject
    private SseBroadcaster broadcaster;

See also:

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720