前边一篇文章中,说了一下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");
}
}