简体   繁体   中英

how to differentiate between different server sent event listeners?

I have a application in which different user listens to server sent event source for a periodical response .I intend to sent response from server with corresponding Id and data in json format.And at client side each client when data arrives checks for matching Id if found it process the data else ignore it.But the flaw in this approach is each user gets data from periodical updates even if it is not intended for them.I read a few articles about sse but could't find anything about this

My question is using server side events is there any way of sending response to specific listeners and if so how .?

UPDATE based on question clarification: how to stop a client receiving SSE messages that are not intended for it.

The best way is not to send it. Filter the messages server-side. (As the earlier part of my answer explains, this is easy, because every SSE connection already has a dedicated server process deciding what data to send to it.) This approach is superior in all ways (CPU/memory, network bandwidth, security, privacy, programmer effort).

The alternative would be to filter it client-side, and there are two ways to do this. One is to be sending json data to the clients. In your onMessage() handler use one of those fields to decide if this message is for this client.

The other would be to use the event: field of SSE, and then listen for that message:

es = new EventSource(...);
es.addEventListener("forUser123", function(e) {
  //Process their data here
  }, false);

The event:forUser123 header would be set on the server, before you send the data: field. (BUT, if you have to go that trouble to add an extra header, it is better to filter the messages you send at this point.)


Original Answer

The thing you want to do (be client-specific) is easy, and the way you thought Server-Sent-Events worked (broadcast) is harder.

Each EventSource connection to your server is a dedicated socket. So it comes through just like any other connection to the web server, the only difference is the socket is not closed, but kept open so the server can continue to send data. This also implies there is one dedicated process or thread on the server for dealing with messages to send to that client.

So, the server knows who each user is (assuming they identify themselves, with say a session cookie), and can choose what data to send that client.

Aside: Why is broadcast harder? Say you have 100 connected SSE clients - you actually have 100 independent server processes running. To broadcast a single message to all 100, you first have to tell those 100 server-side processes what the message is, so that they can pass it on. You might do this with an upstream socket, or they might regularly poll a "messagesToSendToEveryone" database table to see if anything new has been added.

What I did was to register the user /ask the user for login and return a unique Identification key.Using this key as event name event listener is initialized in the post back success function of registration/login $post();.

So basically each event listener listen to a unique event .At server side each event name is broadcasted followed by data so unique event listeners get messages only intended for them.

Clientside

$.post( "chatReg.php", { xxx: xxxx, time: xxx}).done(function( data ) {

     if((typeof(EventSource) !== "undefined")&&((localStorage.getItem("uname") !== null))) {
    var source = new EventSource("XXXXXXXX.php");   

    source.addEventListener(localStorage.getItem("uname"), function(e) {
     var data = JSON.parse(e.data);

     $('div.chat-box-content').append('<div class="msgWrapper"><div class="msgwrapperleft"><div class="iconright"><img src="http://placehold.it/40X40"></img></div><div class="MessageRight">'+data.Message+ '</div> </div><p class="ArrivedTimeRight"><span ><span class="timeago" >'+CreateTimestamp()+'</span></span></p></div>');

    }, false);


    } 

}

Server

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
header("refresh: 5;");

    echo  'event: '.$row['SpecialId'];
            echo PHP_EOL;

            echo  'data: {"Message":"'.$row['Message'].'","xxxId":"'.$row['xxxId'].'"}';
            echo PHP_EOL;
            echo PHP_EOL;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM