Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Server Sent Event send response to a specific client

In Server Sent Event, it always send the same response to all the client. but what i want to know is, How to send response to an only one client using java.

this is my event which define inside sw.js (SSE)

var eventSource = new EventSource("HelloServlet");
eventSource.addEventListener('up_vote',function(event){
    console.log("data from s" , event.data);
    var title = event.data;
    self.registration.showNotification(title, {
          'body': event.data,
          'icon': 'images/icon.png'
        })
});

I want to show this notification only to an specific user. not for everyboday. HelloServlet is my servlet and it contain this,

response.setContentType("text/event-stream");   
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = response.getWriter();
        String upVote = "u";
        String downVote = "d";
        for(int i=0; i<10; i++) {
            writer.write("event:up_vote\n");
            writer.write("data: "+ upVote +"\n\n");
            writer.write("event:down_vote\n");
            writer.write("data: "+ downVote +"\n\n");
            writer.flush();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        writer.close();
like image 426
YM-91 Avatar asked Jan 25 '16 12:01

YM-91


3 Answers

The reason that you are only sending the same message to all clients is because you only have one channel that they are all connected to. The EventSource is just a GET request that you are leaving open. Like any get request you can make it bespoke to a particular user in a couple of ways.

var eventSource = new EventSource("HelloServlet?username=their-user-name");

In this example you are using the query string to create a unique channel for each person. You would then need logic on the server-side to send different content depending on the username variable.

You could also use sessions. So you could keep the current code on the client.

var eventSource = new EventSource("HelloServlet");

But on the server side you would need to examine the session and then have logic to send different content depending on the session information.

Does that help?

like image 194
baynezy Avatar answered Nov 20 '22 14:11

baynezy


I know the post is very old but it still worth mentioning a solution to this problem. I had more or less same use case where I need to publish notifications to users and each user will have their own notifications. I used a simple trick, EventSource listen to events and I appended userId as a part of event type to distinguish among users. So instead of on up_vote, I used up_vote_userId1. And our backend based on which user has an update publish the events to these event type. And our problem solved.

like image 20
Prabhay Avatar answered Nov 20 '22 13:11

Prabhay


I recommend you the JEaSSE library (Java Easy Server-Sent Events): http://mvnrepository.com/artifact/info.macias/jeasse

You can find some usage examples here: https://github.com/mariomac/jeasse

Specifically, for your use case:

@WebServlet(asyncSupported = true)
public class ExampleServlet1 extends HttpServlet {

    SseDispatcher dispatcher;;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                                      throws ServletException, IOException {
       dispatcher = new SseDispatcher(req).ok().open();
    }

    public void onGivenEvent(String info) {
       dispatcher.send("givenEvent",info);
    }
}
like image 1
Mario Avatar answered Nov 20 '22 12:11

Mario