前边一篇文章中,说了一下WCF和Asp.net的session共享,现在实现Silverlight的过期退出和WCF服务session失效的同步方案。
Silverlight的bussiness模板中已经包含了超时认证的部分,现作为借鉴,实现了WCF服务端session失效和Silverlight过期的同步。
1. 在web.config中设置session过期的时间:
<sessionState mode="InProc" stateConnectionString= "tcpip=127.0.0.1:42424" cookieless="false" timeout="60"/>
2. 在aspx的页面中读取其配置过期时间到silverlight中。
public partial class Default : System.Web.UI.Page { protected override void OnLoad(EventArgs e) { if (!User.Identity.IsAuthenticated) { string url = Request.Url.ToString(); url = url.Replace("&", "%26"); string urlBase64 = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(url)); string urlRedirect = string.Format("{0}?ReturnUrl={1}", FormsAuthentication.LoginUrl, urlBase64); Response.Redirect(urlRedirect); return; } else { UserId = HttpContext.Current.User.Identity.Name; // 读取session过期时间 int formTimeOut =(int)FormsAuthentication.Timeout.TotalMinutes; Timeout = HttpContext.Current.Session.Timeout >= formTimeOut ? formTimeOut : HttpContext.Current.Session.Timeout; } base.OnLoad(e); } protected void Page_Load(object sender, EventArgs e) { } public string UserId { get; set; } public int Timeout { get; set; } }
3.把Timeout传人参数到silverlight端:
<param name="initParams" value="userId=<%=UserId%>,timeOut=<%=Timeout%>"/>
4.在silverlight中读取过期时间值,进行过期退出实现
private void Application_Startup(object sender, StartupEventArgs e) { _timeOut = Convert.ToInt32(e.InitParams["timeOut"]); FormsWithTimeoutAuthentication formsWithTimeoutAuthentication = new FormsWithTimeoutAuthentication(_timeOut); // 短于服务端 formsWithTimeoutAuthentication.EndLogin(true); }
formsWithTimeoutAuthentication 类得实现:
public class FormsWithTimeoutAuthentication { private DispatcherTimer idleTimer; private int minutesIdle; private bool idle; private bool attached = false; private CommonProxy.CommonServicesClient commomProxy = null; public FormsWithTimeoutAuthentication() : this(20) { } public FormsWithTimeoutAuthentication(int idleMinutes) { IdleMinutesBeforeTimeout = idleMinutes; idleTimer = new DispatcherTimer(); idleTimer.Interval = TimeSpan.FromMinutes(1); idleTimer.Tick += new EventHandler(idleTimer_Tick); } public int IdleMinutesBeforeTimeout { get; set; } public void EndLogin(bool loginRes) { if (loginRes == true) { if (!attached) AttachEvents(); minutesIdle = 0; idleTimer.Start(); } } protected void EndLogout() { idleTimer.Stop(); } private void AttachEvents() { attached = true; //Application.Current.RootVisual.MouseMove += new MouseEventHandler(RootVisual_MouseMove); Application.Current.RootVisual.KeyDown += new KeyEventHandler(RootVisual_KeyDown); Application.Current.RootVisual.MouseLeftButtonUp += new MouseButtonEventHandler(RootVisual_MouseLeftButtonUp); Application.Current.RootVisual.MouseRightButtonDown += new MouseButtonEventHandler(RootVisual_MouseRightButtonDown); Application.Current.RootVisual.MouseWheel += new MouseWheelEventHandler(RootVisual_MouseWheel); } void RootVisual_MouseWheel(object sender, MouseWheelEventArgs e) { idle = false; } void RootVisual_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { idle = false; } void RootVisual_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { idle = false; } private void RootVisual_KeyDown(object sender, KeyEventArgs e) { idle = false; } private void RootVisual_MouseMove(object sender, MouseEventArgs e) { idle = false; } private void idleTimer_Tick(object sender, EventArgs e) { if (idle == true) { minutesIdle += idleTimer.Interval.Minutes; if (minutesIdle >= IdleMinutesBeforeTimeout) { Logout(); } } else { minutesIdle = 0; } idle = true; } public void Logout() { EndLogout(); //这里是你自己的退出登录代码,我这里是调用WCF的配置的退出地址,退出界面,刷新页面而已 commomProxy = new CommonServicesClient(); commomProxy.GetConfigValuebyConfigKeyCompleted += (sender, e) => { if(e.Error == null) { if (!string.IsNullOrEmpty(e.Result)) HtmlPage.Window.Navigate(new Uri( e.Result, UriKind. Absolute)); } }; commomProxy.GetConfigValuebyConfigKeyAsync("LogoutRedirectUrl"); } }