6

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?

user
  • 19,934
  • 9
  • 108
  • 94
Junior
  • 10,784
  • 25
  • 91
  • 192
  • __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 Aug 28 '15 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 Aug 28 '15 at 18:56
  • Possible duplicate of [Is there a way to make Using server-sent events persistent?](http://stackoverflow.com/questions/31143150/is-there-a-way-to-make-using-server-sent-events-persistent) – user Jan 12 '16 at 10:43

3 Answers3

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 computers.

Ghedipunk
  • 1,229
  • 10
  • 22
1
  • 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 becomes an inter-tab communication issue: the first tab needs to have a way to detect the second tab is there, and has to have a way to communicate 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.)

Darren Cook
  • 26,177
  • 12
  • 103
  • 206
  • Thank you for your feedback. I appreciate your thought. I already have implementation for `session_wire_close()` as I got bit before with the same thing :) I think you are right about the SharedWorker suggestion. I am trying to implement it but no success so far. I will let you know how it goes. – Junior Aug 30 '15 at 17:16
0

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.

Dean Jenkins
  • 184
  • 5