最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there a way to have one server-sent-event running per user not per tab? - Stack Overflow

programmeradmin1浏览0评论

I am running into many issues because my users use multiple browser's tabs to use the same application.

The problem is that each tab will make a separate connection to the server to start server-sent events and the server will run a loop to fulfill the request. (if there are 5 tabs open per user then the server will have to start 5 different server-sent-event to respond!)

Is there a way to add some sort of logic to check if there is a connection established between a client and the server-sent script use the same connection instead of creating a new one?

I think this would be the same idea of using a WebSocket. However, the problem with me using WebSockets that each user must be authenticated using the server-sent event and not sure if this is possible with WebSockets. When a user logs in to the app, I generate a sessionID and the session checks their IPs/agent data to match before they are allowed to use the site.

How can I minimize the connection to the Server-Sent Event to 1 per user?

I am running into many issues because my users use multiple browser's tabs to use the same application.

The problem is that each tab will make a separate connection to the server to start server-sent events and the server will run a loop to fulfill the request. (if there are 5 tabs open per user then the server will have to start 5 different server-sent-event to respond!)

Is there a way to add some sort of logic to check if there is a connection established between a client and the server-sent script use the same connection instead of creating a new one?

I think this would be the same idea of using a WebSocket. However, the problem with me using WebSockets that each user must be authenticated using the server-sent event and not sure if this is possible with WebSockets. When a user logs in to the app, I generate a sessionID and the session checks their IPs/agent data to match before they are allowed to use the site.

How can I minimize the connection to the Server-Sent Event to 1 per user?

Share Improve this question edited Jan 12, 2016 at 10:50 user 25.9k11 gold badges117 silver badges104 bronze badges asked Aug 28, 2015 at 18:28 JuniorJunior 12k32 gold badges120 silver badges226 bronze badges 3
  • This is purely a theory. How about creating a random string per user's request (say 7ca5c99ae8), embedding it in generated HTML and accepting another request only if it returns exactly 7ca5c99ae8 to server during request (you may prefer POST over GET for it). Imagine a user using 2 browser tabs (b1 and b2), sends request from b1 without auth number, server generates 59c97bd797a in session and embeds it in returned HTML, next he makes a request from b2 without number (it wasn't sent to b2), but server expected auth 59c97bd797a, fails it and doesn't process it. – DeDee Commented Aug 28, 2015 at 18:49
  • @DeDee that is not bad of a theory. I think it only leads me to one problem. is that the new browsers will not have a server-sent- event since only the one browser can make connection. I don't think there would be a way around this since I can't have 1 PHP script to feed more than 1 browser. – Junior Commented Aug 28, 2015 at 18:56
  • Possible duplicate of Is there a way to make Using server-sent events persistent? – user Commented Jan 12, 2016 at 10:43
Add a ment  | 

4 Answers 4

Reset to default 3

The HTTP headers (and thus, cookies) are available to the WebSocket server while setting up each client's connection.

However, since you're not using WebSockets (yet?), the next best place to go is your client Javascript.

Cookies are available there, unless the cookie has the HttpOnly flag set. This will be your most reliable way to match a user across multiple browser tabs.

The browser user agent string plus their IP address is tempting, but keep in mind that most household routers use NAT, and many people who are living together will tend to use the same browser on their different puters.

  • Limit to one user per connection? Yes.
  • Get multiple tabs to share the same SSE connection? Yes, theoretically.

Expanding on the first point: you mentioned you are using PHP sessions. The session cookie will be sent from each of your tabs, so when the first tab connects, your PHP script can set something inside the session (*) to say you now have an SSE connection. When the second tab connects, your PHP script would look for that session variable, see it, and return an error code.

Regarding the second point, this bees an inter-tab munication issue: the first tab needs to have a way to detect the second tab is there, and has to have a way to municate with it, so that it can forward the SSE messages it receives. I believe HTML5 Shared Web Workers can achieve this, and I have seen people suggest using it for the SSE use-case you describe, but I've yet to see a working example.

*: remember to use session_write_close to close the session once your PHP script starts feeding SSE data back, so that other scripts can use the session. (PHP sessions are locked for the lifetime of the script by default.)

If the user is authenticated then you presumably have some record of users. Add a session ID to that record of users so that only that one will be responded to.

It sounds like you are trying to prevent concurrent use with the same authentication details. The best way of doing that IMHO is to silently ignore concurrent requests.

This is a good question, and a response many years later, but your use case seems a bit odd

Base on your quotes below. My users use multiple tabs to use the same application. Well, for one thing, are they expecting to see the same data on each tab? I don't under stand why that would be necessary? If the other tab is open you want to worry about the tab that is in focus?

Now, if they have multiple tabs open to consume different information i.e. a financial application with 1. being US stock market 2. being British stock market 3. being Asian stock market. That I could understand. But it would also exclude you from using blur handling. Meaning, I prefer to turn the connection "off" if a user clicks away from the tab and report that back to the server to close().

If you don't do that then you should have your timeouts really under control because that !will lead to a lot of memory leaks. So, beware. Users will do anything you let them.

One mechanism you could employ is an active blur session. Meaning, if the user clicks off the tab, blur, you could set a time-out for an expected period of usage. If the screen is the active screen then you could refresh the connection and restart the timer.

So, to me yes, getting a tab from an authenticated user and open up multiple tabs is easy. in fact, that's the default. But that's also the problem.

When you say:

Is there a way to add some sort of logic to check if there is a connection established between a client and the server-sent script use the same connection instead of creating a new one?

What I would do if getting that data onto multiple tabs was a big issue. To me I like the "hey you get one tab sir/mam" and that's it approach.

I would explore a blur approach that would take the data from the open stream and either add it to the browser session in a redux or ngrx abstraction or a data stream abstraction ( both have a plexity of setting up ).

What this would do is say, "if user clicks off tab" (not active tab) then default to the backup data stream from the ining event stream. So, shut off the main stream and go the generated array of data that is ining from the stream. Running off of the in memory/redux/ngrx or a sperate server like Redis or Mongo.

Auth0 has a good example of this in an article.

Handling Connection Recovery on Server-Sent Events

In this example the post person explains that it is possible to handle a lost connection and a recovery by keeping track of the messages sent and if a connection is lost there is a signal to the server. Last-Event-Id Which will tell the user the last correct message that was sent and to deliver the messing messages to the user plus the new ones in order.

Now, this example isn't exactly what you need to do but the point is the same. Save the messages and deliver them a different way so you can shut down the other tabs when the user clicks away from them. This way you will have 1 sse connection on the active tab and the other tabs will just run a carbon copy from some other mechanism. Keeping the connection quality and only one.

Hope this helps someone.

I am running into many issues because my users use multiple browser's tabs to use the same application.

The problem is that each tab will make a separate connection to the server to start server-sent events and the server will run a loop to fulfill the request. (if there are 5 tabs open per user then the server will have to start 5 different server-sent-event to respond!)

Is there a way to add some sort of logic to check if there is a connection established between a client and the server-sent script use the same connection instead of creating a new one?

发布评论

评论列表(0)

  1. 暂无评论