ASP.NET MVC4 三种方法实现在线人数统计.
一:利用session的SqlServer模式
原理:session的SqlServer模式可以长期存用户session数据 在sqlserver表里面 那么我们就需要一条查询语句就可以知道当前在线人数
开始配置:
1.打来cmd->输入C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe -ssadd -sstype c -d <你的数据库名称> -S <你的SQL IP> -U <帐号> -P <密码>
例如我的命令:C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe -ssadd -sstype c -d Counter -S . -U sa -P 123456
执行完后 数据库会多出两张表 aspstatetempsession这张表就会记录session信息
2.webconfig 中的配置
<sessionState mode="SQLServer" sqlConnectionString="data source=.;initial catalog=Counter;user id=sa;password=123456" allowCustomSqlDatabase="true" timeout="120"></sessionState>
</system.web>
view页代码:
@{
ViewBag.Title = "Home Page";
Layout = null;
}
当前在线人数:<strong>@ViewBag.tatol</strong>
conctroll 代码:
public class HomeController : Controller
{
public ActionResult Index()
{
string strconn = "server=.;database=Counter;user id=sa;password=123456";
SqlConnection conn = new SqlConnection(strconn);
conn.Open();
SqlCommand comm = new SqlCommand("select COUNT(1) from ASPStateTempSessions",conn);
var total = comm.ExecuteScalar();
conn.Close();
ViewBag.tatol = total;
return View();
}
}
效果图:
session值过期后 数据库才会清除数据 所以当我关闭IE浏览器后 刷新chrome浏览器人数还是2
二:利用Session,Application
需要四个事件:Application_Start()事件、Application_End()、Session_Start()事件和Session_End()事件。
它们都在Global.asax.cs文件中
protected void Application_Start()//程序启动时进入此方法
{ //默认配置
GlobalConfiguration.Configure(WebApiConfig.Register);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//连接数据库 获取总访问量数据
string sqlconn = "server=.;database=OnLine;user id=sa;pwd=123456";
SqlConnection conn = new SqlConnection(sqlconn);
conn.Open();
SqlCommand cmd = new SqlCommand("select Total from StatisticsNubmer ", conn);
int count = (int)cmd.ExecuteScalar();
Application["total"] = count;//总人数
Application["onLine"] = 0;//当前在线人数变量
conn.Close();
}
protected void Session_Start()//新建Session连接后访问
{
Application.Lock(); //锁定Application
Application["total"] = (int)Application["total"] + 1; //总访问量加1
Application["onLine"] = (int)Application["onLine"] + 1; //在线人数加1
Application.UnLock();//解锁
}
Application执行了Lock()方法之后, 整站中所有关于Application的操作都会被锁定延时执行,包括Application赋值和Application读取),只让一个客户端进行这两个变量的自增,之后再进行解锁,供其他客户端进行操作。
protected void Session_End()//用户断开连接session过期后访问
{
Application.Lock(); //锁定Application
Application["onLine"] = (int)Application["onLine"] - 1; //总访问数量不变,在线人数减1
Application.UnLock(); //解除锁定
}
protected void Application_End()//当回收IIS池或更改bin文件夹或web.config文件时,将触发该事件。您应该更改默认的IIS设置,以便在非高峰时段每天安排一次回收。
{
//将访问总数量更新到数据库
string sqlconn = "server=.;database=OnLine;user id=sa;pwd=123456";
SqlConnection conn = new SqlConnection(sqlconn);
conn.Open();
SqlCommand cmd = new SqlCommand("update StatisticsNubmer set [email protected] ", conn);
cmd.Parameters.Add(new SqlParameter("@Total",Application["total"]));
}
效果图:
和第一种方法一样 当我关闭左边chrome浏览器后 刷新IE浏览器 当前人数不会发生变化 因为Session没有过期
当然为了测试你可以把过期时间缩短一点
三:使用SignalR2即时在线人数监控
1.工具->NuGet管理 搜索signalr
安装后新增Hubs文件夹 新建Counter类
counter类 代码:
namespace Realtime.Hubs
{
public class Counter:Hub
{
static long counter = 0;//在线人数
public override System.Threading.Tasks.Task OnConnected()//建立连接时访问
{
counter = counter + 1;//当用户进入页面在线人数加一
Clients.All.UpdateCount(counter);//调用客户端方法更新接口
return base.OnConnected();
}
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)//断开连接时访问
{
counter = counter - 1;
Clients.All.UpdateCount(counter);
return base.OnDisconnected(stopCalled);
}
}
}
Index视图页代码:
@{
ViewBag.Title = "Home Page";
Layout = null;
}
<div>
当前在线人数:<strong id="counter"></strong>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>//引用的js的顺序不能乱
<script src="~/Scripts/jquery.signalR-2.4.0.min.js"></script>
<script src="~/signalr/hubs"></script>
<script>
$(function () {
//您可以看到集线器差异的名称,当您查看~/signal/hubs的链接时,可以得到正确的名称。
var counter = $.connection.counter;//为counter声明变量
$.connection.hub.start().done(function () {
//连接后可以做一些事情
});
//函数从服务器接收数据,服务器调用代码隐藏
counterhub.client.UpdateCount = function (count)
{
$("#counter").text(count);//赋值
}
})
</script>
</div>
配置startup类:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
ConfigureAuth(app);
}
}
效果图:
这种方法是即时的 当我新开的页面时 所有页面的在线人数加一 关一个页面时 所有页面即时减一(不用刷新)
这是视频地址:https://www.youtube.com/watch?v=EKv39fGfHEY&list=PLiQDVYTaolc92qqHnWNYs6-YWZnIGh1Ma
当然优缺点目前以我的知识面并不能阐述一二。希望后续,学到更多东西的时候, 可以回过头来解释清楚。
上面几种方法,都可以拿来练练手,相信你一定可以学到很多新知识。