ASP.NET सत्र खुला रखना / जिंदा रखना


115

जब तक उपयोगकर्ता ब्राउज़र की खिड़की खुला है, तब तक ASP.NET सत्र को जीवित रखने का सबसे आसान और सबसे आसान तरीका क्या है? क्या यह AJAX कॉल समयबद्ध है? मैं निम्नलिखित को रोकना चाहता हूं: कभी-कभी उपयोगकर्ता अपनी खिड़की को लंबे समय तक खुला रखते हैं, फिर सामान दर्ज करते हैं, और सर्वर साइड सत्र समाप्त होने के बाद कुछ भी काम नहीं करता है। मैं सर्वर पर 10 मिनट से अधिक समय के लिए टाइमआउट मान नहीं बढ़ाना चाहता क्योंकि मैं बंद सत्र (ब्राउज़र विंडो को बंद करके) तेजी से समाप्त करना चाहता हूं।

सुझाव, कोड नमूने?


उत्तर पाने के लिए आप इस लिंक की जाँच कर सकते हैं और साथ ही साथ डॉटनेटस्करी.com
डेवलपर

जवाबों:


170

मैं एक साधारण AJAX कॉल को एक डमी HTTP हैंडलर को करने के लिए JQuery का उपयोग करता हूं जो मेरे सत्र को जीवित रखने के अलावा कुछ नहीं करता है:

function setHeartbeat() {
    setTimeout("heartbeat()", 5*60*1000); // every 5 min
}

function heartbeat() {
    $.get(
        "/SessionHeartbeat.ashx",
        null,
        function(data) {
            //$("#heartbeat").show().fadeOut(1000); // just a little "red flash" in the corner :)
            setHeartbeat();
        },
        "json"
    );
}

सत्र हैंडलर जितना सरल हो सकता है:

public class SessionHeartbeatHttpHandler : IHttpHandler, IRequiresSessionState
{
    public bool IsReusable { get { return false; } }

    public void ProcessRequest(HttpContext context)
    {
        context.Session["Heartbeat"] = DateTime.Now;
    }
}

कुंजी IRequiresSessionState को जोड़ने के लिए है, अन्यथा सत्र उपलब्ध नहीं होगा (= null)। हैंडलर निश्चित रूप से एक JSON क्रमांकित ऑब्जेक्ट को वापस कर सकता है यदि कुछ डेटा को कॉलिंग जावास्क्रिप्ट पर लौटाया जाना चाहिए।

Web.config के माध्यम से उपलब्ध कराया गया है:

<httpHandlers>
    <add verb="GET,HEAD" path="SessionHeartbeat.ashx" validate="false" type="SessionHeartbeatHttpHandler"/>
</httpHandlers>

14 अगस्त, 2012 को बेल्केन्ड्रे से जोड़ा गया

मुझे इस उदाहरण का इतना पसंद आया, कि मैं HTML / CSS और बीट भाग के साथ सुधार करना चाहता हूं

इसे बदलो

//$("#heartbeat").show().fadeOut(1000); // just a little "red flash" in the corner :)

में

beatHeart(2); // just a little "red flash" in the corner :)

और जोड़

// beat the heart 
// 'times' (int): nr of times to beat
function beatHeart(times) {
    var interval = setInterval(function () {
        $(".heartbeat").fadeIn(500, function () {
            $(".heartbeat").fadeOut(500);
        });
    }, 1000); // beat every second

    // after n times, let's clear the interval (adding 100ms of safe gap)
    setTimeout(function () { clearInterval(interval); }, (1000 * times) + 100);
}

HTML और CSS

<div class="heartbeat">&hearts;</div>

/* HEARBEAT */
.heartbeat {
    position: absolute;
    display: none;
    margin: 5px;
    color: red;
    right: 0;
    top: 0;
}

यहाँ केवल पिटाई वाले भाग के लिए एक जीवंत उदाहरण है : http://jsbin.com/ibagob/1/


@veggerby "एक डमी HTTP हैंडलर के लिए जो मेरे सत्र को जीवित रखने के अलावा कुछ नहीं करता है"। क्या आप सत्र को जीवित रखने के लिए HTTP हैंडलर का नमूना कोड पोस्ट कर सकते हैं?
गोपीनाथ

नहीं, और आपका एकमात्र विकल्प वहाँ (मुझे लगता है) सत्र समय-सीमा को बढ़ाना है, लेकिन यह शायद लंबे समय में एक बुरा विचार है
veggerby

संबंधित मुद्दे पर जांच कर रहा था और इस समाधान पर आया था। अच्छी चीज़। एक क्वेरी हालांकि, अगर उपयोगकर्ता अपने ब्राउज़र को खुला छोड़ देता है, और कहता है कि पीसी 10 घंटे तक नहीं सोता है, तो सत्र को इतने लंबे समय तक जीवित रखा जाएगा, है ना? क्या यह सही है?
जुलियस ए

2
अच्छा काम है, लेकिन यह मेरे लिए विफल रहा जब तक कि मैंने कॉल में कैश फट नहीं जोड़ा। इस कैश फट पैरामीटर के बिना नियंत्रक को पहली बार कहा जाता है
जीन

1
@ इसके लिए इसका अर्थ सत्र मूल्य होना है, न कि टाइमआउट या कुछ भी। उपयोग करने का कारण DateTime.Nowसिर्फ यह स्पष्ट करना था कि जब सत्र आखिरी बार दिल की धड़कन के माध्यम से अपडेट किया गया था।
veggerby

69

यदि आप ASP.NET MVC का उपयोग कर रहे हैं - तो आपको अतिरिक्त HTTP हैंडलर और web.config फ़ाइल के कुछ संशोधनों की आवश्यकता नहीं है। आपको बस एक होम / कॉमन कंट्रोलर में कुछ सरल क्रिया जोड़ने की जरूरत है:

[HttpPost]
public JsonResult KeepSessionAlive() {
    return new JsonResult {Data = "Success"};
}

इस तरह जावास्क्रिप्ट कोड का एक टुकड़ा लिखें (मैंने इसे साइट की जावास्क्रिप्ट फ़ाइल में डाल दिया है):

var keepSessionAlive = false;
var keepSessionAliveUrl = null;

function SetupSessionUpdater(actionUrl) {
    keepSessionAliveUrl = actionUrl;
    var container = $("#body");
    container.mousemove(function () { keepSessionAlive = true; });
    container.keydown(function () { keepSessionAlive = true; });
    CheckToKeepSessionAlive();
}

function CheckToKeepSessionAlive() {
    setTimeout("KeepSessionAlive()", 5*60*1000);
}

function KeepSessionAlive() {
    if (keepSessionAlive && keepSessionAliveUrl != null) {
        $.ajax({
            type: "POST",
            url: keepSessionAliveUrl,
            success: function () { keepSessionAlive = false; }
        });
    }
    CheckToKeepSessionAlive();
}

जावास्क्रिप्ट फ़ंक्शन को कॉल करके इस कार्यक्षमता को प्रारंभ करें:

SetupSessionUpdater('/Home/KeepSessionAlive');

कृपया ध्यान दें! मैंने यह कार्यक्षमता केवल अधिकृत उपयोगकर्ताओं के लिए लागू की है (ज्यादातर मामलों में मेहमानों के लिए सत्र स्थिति रखने का कोई कारण नहीं है) और सत्र राज्य को सक्रिय रखने का निर्णय केवल ब्राउज़र पर आधारित नहीं है - ब्राउज़र खुला है या नहीं, लेकिन अधिकृत उपयोगकर्ता को कुछ गतिविधि करनी चाहिए साइट पर (एक माउस ले जाएँ या कुछ कुंजी टाइप करें)।


3
एमवीसी के लिए मुझे लगता है कि यह बेहतर उत्तर है। .Ashx फ़ाइल का उपयोग करने की आवश्यकता नहीं है, आप क्यों करेंगे?
arame3333

Asp mvc में HTTP हैंडलर के साथ यह जाँच करें , आशा है कि कोई मदद करता है।
शैजुत

3
मेरीन, आप भी @Url.Action("KeepSessionAlive","Home")शुरुआती समारोह में उपयोग करना चाह सकते हैं ताकि आपको यूआरएल को हार्डकोड न करना पड़े और एक आईआईएफई के अंदर पहला ब्लॉक भी फेंक दें और बस निर्यात करें SetupSessionUpdaterक्योंकि केवल एक चीज है जिसे बाहरी रूप से लागू करने की आवश्यकता है - कुछ ऐसा यह: सेशनअपडेटर.जेएस
काइलमिट

क्या कोई कारण है कि setInterval का उपयोग क्यों नहीं किया जाता है? setInterval(KeepSessionAlive, 300000)
मैथ्यू कॉर्मियर

8

जब भी आप सर्वर से अनुरोध करते हैं तो सत्र समय समाप्त हो जाता है। तो आप सर्वर पर खाली HTTP हैंडलर को केवल एक अजाक्स कॉल कर सकते हैं, लेकिन सुनिश्चित करें कि हैंडलर का कैश अक्षम है, अन्यथा ब्राउज़र आपके हैंडलर को कैश करेगा और एक नया अनुरोध नहीं करेगा।

KeepSessionAlive.ashx.cs

public class KeepSessionAlive : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
            context.Response.Cache.SetNoStore();
            context.Response.Cache.SetNoServerCaching();
        }
    }

.js:

window.onload = function () {
        setInterval("KeepSessionAlive()", 60000)
}

 function KeepSessionAlive() {
 url = "/KeepSessionAlive.ashx?";
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", url, true);
        xmlHttp.send();
        }

@veggerby - सत्र में भंडारण चर के ओवरहेड की कोई आवश्यकता नहीं है। बस सर्वर के लिए एक अनुरोध preforming पर्याप्त है।


2

क्या आपको वास्तव में सत्र रखने की आवश्यकता है (क्या आपके पास इसमें डेटा है?) या अनुरोध में आने पर सत्र को फिर से बहाल करके इसे नकली करना पर्याप्त है? यदि पहले, ऊपर विधि का उपयोग करें। यदि दूसरा है, तो Session_End ईवेंट हैंडलर का उपयोग करके कुछ आज़माएं।

यदि आपके पास प्रपत्र प्रमाणीकरण है, तो आपको Global.asax.cs में कुछ मिलता है

FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formsCookie.Value);
if (ticket.Expired)
{
    Request.Cookies.Remove(FormsAuthentication.FormsCookieName);
    FormsAuthentication.SignOut();
    ...             
     }
else
{   ...
    // renew ticket if old
    ticket = FormsAuthentication.RenewTicketIfOld(ticket);
    ...
     }

और आप सत्र जीवनकाल की तुलना में टिकट जीवनकाल को बहुत लंबा सेट करते हैं। यदि आप एक अलग प्रमाणीकरण विधि का प्रमाणीकरण या उपयोग नहीं कर रहे हैं, तो समान चालें हैं। Microsoft TFS वेब इंटरफ़ेस और SharePoint इनका उपयोग करते प्रतीत होते हैं - यह दे दूर है कि यदि आप एक बासी पृष्ठ पर एक लिंक पर क्लिक करते हैं, तो आपको पॉपअप विंडो में प्रमाणीकरण संकेत मिलते हैं, लेकिन यदि आप बस एक कमांड का उपयोग करते हैं, तो यह काम करता है।


2

आप सिर्फ जावा स्क्रिप्ट फाइल में इस कोड को लिख सकते हैं।

$(document).ready(function () {
        var delay = (20-1)*60*1000;
        window.setInterval(function () {
            var url = 'put the url of some Dummy page';
            $.get(url);                
        }, delay);
});

(20-1)*60*1000ताज़ा समय है, यह सत्र टाइमआउट ताज़ा होगी। रिफ्रेश टाइमआउट की गणना आईआईएस = 20 मिनट से डिफ़ॉल्ट समय के रूप में की जाती है, जिसका अर्थ है 20 × 60000 = 1200000 मिलीसेकंड - 60000 मिलीसेकंड (सत्र समाप्त होने से एक मिनट पहले) 1140000 है।


0

यहां एक वैकल्पिक समाधान है जो क्लाइंट पीसी के स्लीप मोड में चले जाने पर बच जाना चाहिए।

यदि आपके पास उपयोगकर्ताओं की एक बड़ी मात्रा है, तो इसे सावधानी से उपयोग करें क्योंकि यह बहुत अधिक सर्वर मेमोरी खा सकता है।

आपके लॉगिन के बाद (मैं लॉगिन नियंत्रण की लॉग इन घटना में ऐसा करता हूं)

Dim loggedOutAfterInactivity As Integer = 999 'Minutes

'Keep the session alive as long as the authentication cookie.
Session.Timeout = loggedOutAfterInactivity

'Get the authenticationTicket, decrypt and change timeout and create a new one.
Dim formsAuthenticationTicketCookie As HttpCookie = _
        Response.Cookies(FormsAuthentication.FormsCookieName)

Dim ticket As FormsAuthenticationTicket = _
        FormsAuthentication.Decrypt(formsAuthenticationTicketCookie.Value)
Dim newTicket As New FormsAuthenticationTicket(
        ticket.Version, ticket.Name, ticket.IssueDate, 
        ticket.IssueDate.AddMinutes(loggedOutAfterInactivity), 
        ticket.IsPersistent, ticket.UserData)
formsAuthenticationTicketCookie.Value = FormsAuthentication.Encrypt(newTicket)

यह नीचे मतदान क्यों किया गया था? वहाँ के साथ समस्या का कुछ प्रकार है कि मैं उल्लेख नहीं किया है? अगर ऐसा है तो कृपया शेयर करें ताकि भविष्य के पाठक इससे अवगत हों!
पीटर

0

मैंने कुछ दिन बिताए यह जानने का प्रयास किया कि पॉपअप संवाद के माध्यम से वेबफार्म में एक उपयोगकर्ता सत्र को कैसे लम्बा किया जाए, जिससे उपयोगकर्ता को सत्र को नवीनीकृत करने या इसे समाप्त करने की अनुमति देने का विकल्प मिल सके। # 1 बात जो आपको जानना आवश्यक है, वह यह है कि आपको इस फैंसी 'HttpContext' सामान की जरूरत नहीं है, जो कुछ अन्य जवाबों में चल रही है। आपको केवल jQuery के $ .post () की आवश्यकता है; तरीका। उदाहरण के लिए, डिबगिंग के दौरान मैंने प्रयोग किया:

$.post("http://localhost:5562/Members/Location/Default.aspx");

और अपनी लाइव साइट पर आप कुछ इस तरह का उपयोग करेंगे:

$.post("http://mysite/Members/Location/Default.aspx");

यह उतना ही आसान है। इसके अलावा, यदि आप उपयोगकर्ता को अपने सत्र को नवीनीकृत करने के विकल्प के साथ संकेत देना चाहते हैं, तो निम्न के समान कुछ करें:

    <script type="text/javascript">
    $(function () { 
        var t = 9;
        var prolongBool = false;
        var originURL = document.location.origin;
        var expireTime = <%= FormsAuthentication.Timeout.TotalMinutes %>;

        // Dialog Counter
        var dialogCounter = function() {
            setTimeout( function() {
                $('#tickVar').text(t);
                    t--;
                    if(t <= 0 && prolongBool == false) {
                        var originURL = document.location.origin;
                        window.location.replace(originURL + "/timeout.aspx");
                        return;
                    }
                    else if(t <= 0) {
                        return;
                    }
                    dialogCounter();
            }, 1000);
        }

        var refreshDialogTimer = function() {
            setTimeout(function() { 
                $('#timeoutDialog').dialog('open');
            }, (expireTime * 1000 * 60 - (10 * 1000)) );
        };

        refreshDialogTimer();

        $('#timeoutDialog').dialog({
            title: "Session Expiring!",
            autoOpen: false,
            height: 170,
            width: 350,
            modal: true,
            buttons: {
                'Yes': function () {
                    prolongBool = true;
                    $.post("http://localhost:5562/Members/Location/Default.aspx"); 
                    refreshDialogTimer();
                    $(this).dialog("close");
                },
                Cancel: function () {
                    var originURL = document.location.origin;
                    window.location.replace(originURL + "/timeout.aspx");
                }
            },
            open: function() {
                prolongBool = false;
                $('#tickVar').text(10);
                t = 9;
                dialogCounter();
            }
        }); // end timeoutDialog
    }); //End page load
</script>

अपने HTML में डायलॉग जोड़ना न भूलें:

        <div id="timeoutDialog" class='modal'>
            <form>
                <fieldset>
                    <label for="timeoutDialog">Your session will expire in</label>
                    <label for="timeoutDialog" id="tickVar">10</label>
                    <label for="timeoutDialog">seconds, would you like to renew your session?</label>
                </fieldset>
            </form>
        </div>

0

वेजबर्बी के समाधान के संबंध में, यदि आप इसे वीबी ऐप पर लागू करने की कोशिश कर रहे हैं, तो अनुवादक के माध्यम से आपूर्ति कोड को चलाने की कोशिश करें। निम्नलिखित काम करेगा:

Imports System.Web
Imports System.Web.Services
Imports System.Web.SessionState

Public Class SessionHeartbeatHttpHandler
    Implements IHttpHandler
    Implements IRequiresSessionState

    ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

    Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        context.Session("Heartbeat") = DateTime.Now
    End Sub
End Class

इसके अलावा, दिल की धड़कन की तरह कॉल करने के बजाय () फ़ंक्शन जैसे:

 setTimeout("heartbeat()", 300000);

इसके बजाय, इसे कॉल करें:

 setInterval(function () { heartbeat(); }, 300000);

नंबर एक, सेटटाइमआउट केवल एक बार फायर करता है जबकि सेटइंटरवल बार-बार फायर करेगा। नंबर दो, कॉलिंग हार्टबीट () एक स्ट्रिंग की तरह मेरे लिए काम नहीं करता था, जबकि इसे कॉल करना एक वास्तविक फ़ंक्शन की तरह था।

और मैं पूरी तरह से 100% पुष्टि कर सकता हूं कि यह समाधान GoDaddy के हास्यास्पद फैसले को पार कर जाएगा, जो कि प्लिस्को में 5 मिनट के एपप्लस सत्र के लिए मजबूर करेगा!


0

यहाँ संभाल अनुकूलन के साथ मैरीन समाधान के JQuery प्लगइन संस्करण। केवल JQuery के साथ 1.7+!

(function ($) {
    $.fn.heartbeat = function (options) {
        var settings = $.extend({
            // These are the defaults.
            events: 'mousemove keydown'
            , url: '/Home/KeepSessionAlive'
            , every: 5*60*1000
        }, options);

        var keepSessionAlive = false
         , $container = $(this)
         , handler = function () {
             keepSessionAlive = true;
             $container.off(settings.events, handler)
         }, reset = function () {
             keepSessionAlive = false;
             $container.on(settings.events, handler);
             setTimeout(sessionAlive, settings.every);
         }, sessionAlive = function () {
             keepSessionAlive && $.ajax({
                 type: "POST"
                 , url: settings.url
                 ,success: reset
                });
         };
        reset();

        return this;
    }
})(jQuery)

और यह आपके * .cshtml में आयात कैसे करता है

$('body').heartbeat(); // Simple
$('body').heartbeat({url:'@Url.Action("Home", "heartbeat")'}); // different url
$('body').heartbeat({every:6*60*1000}); // different timeout

0

[देर से पार्टी करने के लिए ...]

एक अजाक्स कॉल या वेबसर्वर हैंडलर के ओवरहेड के बिना ऐसा करने का एक और तरीका है कि किसी दिए गए समय के बाद एक विशेष ASPX पृष्ठ लोड किया जाए (यानी, सत्र राज्य समय से पहले, जो आमतौर पर 20 मिनट है):

// Client-side JavaScript
function pingServer() {
    // Force the loading of a keep-alive ASPX page
    var img = new Image(1, 1);
    img.src = '/KeepAlive.aspx';
}

KeepAlive.aspxपेज बस एक खाली पृष्ठ के अलावा कुछ नहीं स्पर्श करता है / ताज़ा Sessionराज्य:

// KeepAlive.aspx.cs
public partial class KeepSessionAlive: System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Refresh the current user session
        Session["refreshTime"] = DateTime.UtcNow;
    }
}

यह एक img(छवि) तत्व बनाकर और ब्राउज़र को KeepAlive.aspxपृष्ठ से अपनी सामग्री लोड करने के लिए मजबूर करके काम करता है । उस पृष्ठ को लोड करने से सर्वर को Sessionऑब्जेक्ट को छूने (अपडेट) करने का कारण बनता है , सत्र की समाप्ति स्लाइडिंग विंडो को विस्तारित करना (आमतौर पर 20 मिनट तक)। वास्तविक वेब पेज सामग्री ब्राउज़र द्वारा खारिज कर दी जाती है।

एक वैकल्पिक, और शायद क्लीनर, ऐसा करने का तरीका एक नया iframeतत्व बनाना और KeepAlive.aspxपृष्ठ को उसमें लोड करना है। iframeतत्व इस तरह यह एक छिपा के चाइल्ड तत्व के रूप में बनाने के द्वारा, छिपा हुआ है divपृष्ठ पर तत्व कहीं।

पृष्ठ पर गतिविधि को पूरे पृष्ठ निकाय के लिए माउस और कीबोर्ड क्रियाओं को रोककर पता लगाया जा सकता है:

// Called when activity is detected
function activityDetected(evt) {
    ...
}

// Watch for mouse or keyboard activity
function watchForActivity() {
    var opts = { passive: true };
    document.body.addEventListener('mousemove', activityDetected, opts);
    document.body.addEventListener('keydown', activityDetected, opts);
}

मैं इस विचार का श्रेय नहीं ले सकता; देखें: https://www.codeproject.com/Articles/227382/Alert-Session-Time-out-in-ASP-Net

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.