How to avoid SignalR firing one script for each open tab - asp.net-mvc

I use SignalR to show new mail notifications dynamically. I've recently realized that if there are multiple tabs for the same domain, then the concerned function gets called as many times as the number of the tabs. So for instance, I open the application in IE and login as Brian. Then I open the same application in Chrome in 3 tabs and login as Kevin. When Brian sends mail to Kevin, the script that is responsible for incrementing the number of new mails is called 3 times.
Has anyone come up with a solution for this?

Each tab is considered a separate connection for SignalR and hence you get multiple messages.
You can take inspiration from this.
For more details visit follow another SO question Javascript; communication between tabs/windows with same origin

Related

Disable multi-tab browsing for single session/user

[Disclaimer: I'm not sure if this kind of question is accepted here as it is about a piece of software deployed already. Rest assured I didn't drop any confidential information. Also do tell me if I violated any rules in SO by posting this so I can take it down immediately]
I have a working Learning Management System web application and I recently received a bug report about a button not showing. After investigating, I have proved that the user was not using the web app as intended. When taking an exam, he was opening multiple tabs to exploit the feature that informs him whether the answer was correct or not. He then will use this information to eliminate the wrong answers and submit all the right answers in another tab/window.
I'm using Rails 4.2. Is there a way to prevent multi-tab browsing? I'm thinking like if a user is signed in and he attempted to open a new tab of the webapp, he should see something like "Please use one tab" and all the features/hyperlinks/buttons are disabled.
Here's a screenshot of how I proved he was using multiple tabs. Notice that there are multiple logs of the same attempt # because the current implementation allows saving a study session and resuming later (this is the part that's exploited). The opening of multiple tabs searches for the most recent attempt session and continues from there. This is also the reason why most of the sessions don't have a duration value -- the user only finishes a study session for one tab (by clicking a button that ends the study session). The system cannot compute for the duration because the other sessions don't have an end timestamp.
-
This is what a single-tab user looks like:
This is more of an application misuse issue more than a bug.
You should add protection not only from multi tab, but for multi browsers aw well, so it can't be purely FrontEnd check.
One of the solutions could be using ActionCable to check if a user has an active connection already and then act accordingly.
Another, for example, generate a GUID in JS and pass it with every answer. If its different from previous answer, it means user opened a new window.
But of course the solution would depend on your current architecture, without knowing how do you currently organise client-server communication it's hard to give exact and optimal solution.
I found an answer here. I just placed this js in the application view to prevent any extra instance of the website.
Thanks for everyone who pitched in.

New service worker keeps being added

I'm using polymer and firebase to make a web app, and the generated service worker is acting weird.
So, as you can see, the number of "clients" keeps increasing overtime. A new client is added like every 5 seconds.
What is a possible cause of this?
My guess here is that you have a lot of tabs open. I saw that happen to my project when I opened up another tab of the same URL. Or you might be missing some event listeners for the SW.

No action method is hit after certain amount of tabs are open in Chrome and Firefox

Is there a limit on number of open tabs for an ASP.NET MVC application to be able to make another request? Why I'm asking this is because, I make some requests in a blank target and after having 5 open tabs, I am not able to invoke any action method unless I close one of those 5. To make sure it's not related to anything that deals with database stuff, I put a breakpoint to the first line of the desired action method. The first 5 requests go super fast. But the sixth one.. The breakpoint doesn't hit on the sixth request. It's only after I close any of the previously opened tabs that the breakpoint hits immediately.
To be honest, I'm not sure if this is even related to ASP.NET MVC, because I have this problem in Chrome and Firefox. With IE10, there's no such problem. Do you have any idea what the problem is?
I'm both glad and sad to have found the reason behind this weird behavior. I use SignalR for realtime notifications. As browsers have maximum number of concurrent connections, which is something around 6, I am not able to open an additional tab that has SignalR connection started. So this is a browser limitation. There are workarounds though. One of them is adopting subdomain approach like facebook does.
Another one is limiting the number of open connections as described in this blogpost

Update partial view in Layout

I'm working on ASP.NET MVC project with C#.
Ok so I have a layout view where I put my partial view which contains just a div that displays notification messages.
Now from some view I have a button that generate a report in 5 minutes in async manner. While the report being generated I need to allow the user to use other areas of the website.
My action method, once the report is generated successfully, simply returns a string "Success", o/w "Fail".
What I want to do is assign that returned string to the div of the partial view which is on the layout page. So this way the user can see the notification from wherever he is within the website.
How can I do this? Thanks.
There's a number of different things going on here. First, you want the server to update the user with the "success" or "fail" status. This requires 1) using web sockets to create a persistent connection between the client and server, allowing the server to talk to the client without requiring the client to first send a request, or 2) long-polling, which is means the client continuously sending requests at a defined interval to see if the server has any updates.
Long-polling (with AJAX) was the only way to achieve this before the advent of web sockets, which are relatively new, and not universally supported. In particular, IIS8+ is required on the server side, and client side, you need a modern browser, which is really any except IE 9 and below. If you can't run the site on IIS8+ or you need to support legacy versions of IE, then you're stuck with long-polling.
However, with either approach, you're tied to a single page. If the user navigates away, web socket connections are closed and long-polling stops. If the user is still on your site, the next page would need to re-establish all this functionality to keep it working. That's not really difficult - just something to be aware of. It just means that you'll need some universal script running on page load across your site for this.
Now as far as replacing the content of your "partial view" goes. You shouldn't look at it that way. I encourage you to read my post: There's no such thing as a "partial view" client-side, where I get into more detail. The TL;DR version is that all of this updating of the client is happening client-side, and at that point, all you have is the browser DOM. There's no concept of a "partial view". If you want to replace a part of the DOM, you must select it and manipulate it. That's all done with JavaScript and it's all on you. There's no easy "replace this partial view" button.

log out if all tabs closed

I have an app, and user and session models there. New session creates when user logs in. and sessiond destroyes if user log out or close browser. But I want to add destroying session if user close all tabs with my app. Is it possible to do from scratch? If no what i should use?
Thanks in advance
You need to use window.name, here there is some solutions to control your application within different tabs: Multiple Tabs
Session variables are server-side, and tab closing is a client-side action, so you'd have to somehow send a signal to the server to clear those session variables.
The most obvious method to me would be to use the browser's onbeforeunload method and ajaxically send something to the server to clear the session.
Now you have to find a way how you will detect all the tabs of your site is closed.Because, if I have your site open in two tabs, this technique will clear the session on the close of the one tab, rendering the other tab useless (not usesless, just the rug might have been pulled from under this page, now that session is gone)

Resources