1.登陆界面:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>*****************</title>
<link href="scripts/vendor/bootstrap/css/bootstrap.css" rel="stylesheet" />
<script src="scripts/vendor/jquery/jquery-3.1.1.min.js"></script>
<link href="scripts/vendor/layer/skin/default/layer.css" rel="stylesheet" />
<script src="scripts/vendor/layer/layer.js"></script>
<script src="scripts/Missile.login/js/login.js"></script>
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-4 column">
</div>
<div class="col-md-4 column" style="margin-top: 25%; background-color: #a79d9d1c;">
<div>
<h3>这是一套可视化布局系统</h3>
</div>
<br />
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="inputEmail3" class="col-sm-3 control-label" >用户名:</label>
<div class="col-sm-9">
<input type="text" class="form-control" placeholder=" 用户名" id="loginid" />
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-3 control-label">密 码:</label>
<div class="col-sm-9">
<input type="password" class="form-control" id="password" placeholder=" 密码" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<div class="checkbox">
<label>
<input type="checkbox" id="oncc" />记住账号密码</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<button type="button" class="btn btn-primary btn-block btn-default" id="btnServer">
按钮</button>
</div>
</div>
</form>
</div>
<div class="col-md-4 column">
</div>
</div>
</div>
</body>
</html>
利用layer独立开的登陆页面的js:
//此js登录方法必要的3个控件id:loginid,password,oncc
//初始参数
var mloginid = "";//用户名
var mpassword = "";//密码
var moncc = "";//记住我
var mcheckcode = "";//验证码
var patrn = /^(\w){6,20}$/;
/*验证码的路径*/
var yzmurl = {
url:'scripts/Missile.login/img/ValidatorImage.aspx',
url1:'暂无'
};
//赋值函数
var setui = function () {
mloginid = $("#loginid").val();
mpassword = $("#password").val();
moncc = $("#oncc").val();
}
//点击登陆时的必填判断 return true
var isft = function (loginname, password) {
if (loginname == undefined || loginname == "") {
layer.msg("请先输入用户名!");
return false;
}
else if (password == undefined || password == "") {
layer.msg("请先输入密码!");
return false;
} else {
return true;
}
};
//判断错误时间10分钟内,错误3次出现验证码登录,错误10次初始需要验证码的时间
var islocadelay = function () {
var gets = parseInt((new Date().getTime() - getLocalDelay().time) / 1000);
if (getLocalDelay().delay != "" && getLocalDelay().delay != undefined && getLocalDelay().delay > 3) {
//大于时间后重新赋值
if (gets >= 600) {
setLocalDelay(0, new Date().getTime());
return false;
} else if (gets < 600 && getLocalDelay().delay > 10) {
setLocalDelay(getLocalDelay().delay, new Date().getTime());
return true;
} else {
return true;
}
} else {
return false;
}
}
//点击登录
var btnServer = function () {
//防止ajax的异步执行
var ansyno = true;
//点击是立即弹加载
//加载层
var loadindex = layer.load(2, { shade: false }); //0代表加载的风格,支持0-2
setui();
if (!isft(mloginid, mpassword)) return layer.close(loadindex);
try {
if (islocadelay()) {
//防止异步-只让单个异步执行
ansyno = false;
//关闭加载层
layer.close(loadindex);
//实现验证码显示html
var yzmhtml ='<div >'
+ '<i class="layui-layer-ico layui-layer-ico4" style="margin-top: 10px;"></i><input id="myinput" placeholder="请输入验证码" style="height: 42px;width: 60 %; margin-left: 30px;" value="" />'
+ '<img id="imgert" alt="" style="height: 42px; margin-top: -2px;" src="' + yzmurl.url + '?randid=' + Math.random() + '"/>'
+ '</div>';
//页面层
layer.open({
area: ['390px', '170px'],
btn: ['确定'],
content:yzmhtml,
yes: function (index, layero) {
//赋值验证码
mcheckcode = $('#myinput').val();
if (mcheckcode != "" && mcheckcode != undefined) {
//关闭y验证码层打开加载层
layer.close(index);
loadindex = layer.load(2, { shade: false });
ansytion();
} else {
layer.msg("请验证码!", { type: 1 }, function (index) {
layer.close(index);
});
}
}
});
$("#imgert").on("click", function () {
console.log(111);
$("#imgert").attr("src", "scripts/Missile.login/img/ValidatorImage.aspx?randid=" + Math.random());
});
}
//方法内置方法,提出单独模块 ajax提交信息
var ansytion = function () {
$.ajax({
type: "POST",
url: "scripts/Missile.login/server/SystemLogin.ashx",
data: { action: "login", loginname: mloginid, passpwd: mpassword, remember: moncc, mcheckcode: mcheckcode },
success: function (d) {
var _res = JSON.parse(d);
if (_res.error == "0") {
location.href = _res.url;
} else {
//关闭页面加载层,如果是跳转网页则不需要关闭
layer.close(loadindex);
layer.msg(_res.message, { type: 1, zIndex: 19891026 }, function (index) {
layer.close(index);
});
if (_res.error == "1234") {
btnServer();
}
if (getLocalDelay().delay != "" && getLocalDelay().delay != undefined) {
setLocalDelay(getLocalDelay().delay + 1, getLocalDelay().time);
} else {
//当查询错误时添加错误次数纪录
setLocalDelay(0, new Date().getTime());
}
};
},
error: function (result) {
console.log(result);
}
});
}
if (ansyno) {
ansytion();
}
} catch (ex) {
console.log(ex);
}
}
//首次加载
var loginlod = function () {
try {
$.ajax({
type: "post",
url: "scripts/Missile.login/server/SystemLogin.ashx?action=loginload",
success: function (d) {
var _res = JSON.parse(d);
if (_res.loginname != "" && _res.loginname != undefined && _res.passpwd != "" && _res.passpwd != undefined) {
$("#loginid").val(_res.loginname);
$("#password").val(_res.passpwd);
$("#oncc").attr("chicked", true);
};
},
error: function (result) { console.log(result); }
});
} catch (ex) {
console.log(ex);
}
}
//页面加载完成后执行
$(function () {
loginlod();
$("#btnServer").on("click", function (ev) {
btnServer();
});
})
//设置setLocalDelay
var setLocalDelay = function (delay,detime) {
//location.href作为页面的唯一标识,可能一个项目中会有很多页面需要获取验证码。
localStorage.setItem("delay_" + location.href, delay);
localStorage.setItem("time_" + location.href, detime);
}
//获取getLocalDelay()
var getLocalDelay = function () {
var LocalDelay = {};
LocalDelay.delay = localStorage.getItem("delay_" + location.href);
LocalDelay.time = localStorage.getItem("time_" + location.href);
return LocalDelay;
}
利用一般处理程序 处理后台:
using Missile.Sql.Action;
using Missile.user;
using System;
using System.Web;
using System.Web.SessionState;
//静态类方法调用多时使用
using static not_can_fly_missile.Signalr.MissileSavUser;
namespace not_can_fly_missile.scripts.login_server.server
{
/// <summary>
/// SystemLogin 的摘要说明
/// </summary>
public class SystemLogin : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
string action = context.Request["action"].ToString();
switch (action)
{
case "loginload":
loginload(context);
break;
case "login":
login(context);
break;
default:
context.Response.Write("{\"error\":1111,\"message\":\"未找到该方法!\"}");
break;
}
#region 构造函数方法
// System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(action);
// if (methodInfo != null)
// { methodInfo.Invoke(this, new object[] { context });}
#endregion
}
//登路加载方法
public void loginload(HttpContext context)
{
string loginname = "";
string passpwd = "";
//是否记住用户名
HttpCookie slectcooke = context.Request.Cookies["userinfo"];
if (slectcooke != null)
{
loginname = slectcooke.Values["loginid"];
passpwd = slectcooke.Values["passpwd"];
}
context.Response.Write("{\"loginname\":\"" + loginname + "\",\"passpwd\":\"" + passpwd + "\"}");
}
//点击登录方法
public void login(HttpContext context)
{
/*设置接受登录信息参数*/
string loginname = context.Request["loginname"].ToString() ?? "";
string passpwd = context.Request["passpwd"].ToString() ?? "";
string remember = context.Request["remember"].ToString() ?? "";
string mcheckcode = context.Request["mcheckcode"].ToString() ?? "";
/*判断是否有验证码验证,login.js传过来一定有值*/
if (mcheckcode != "")
{
if (context.Session["CheckCode"] == null)
{
context.Response.Write("{\"error\":1234,\"message\":\"Session丢失,请重试。\"}");
return;
}
if (context.Session["CheckCode"].ToString() != mcheckcode)
{
context.Response.Write("{\"error\":1234,\"message\":\"验证码错误,请重试。\"}");
return;
}
}
UserInfo u = MissileSqltion.UserValidate(loginname, passpwd);
if (u == null)
{
context.Response.Write("{\"error\":1000,\"message\":\"用户名或密码错误,请重试。\"}");
return;
}
if (remember == "on")
{
HttpCookie hc = new HttpCookie("userinfo");
hc.Values.Add("loginid", loginname);
hc.Values.Add("passpwd", passpwd);
hc.Expires = DateTime.Now.AddDays(7);
HttpContext.Current.Response.Cookies.Add(hc);
}
else {
HttpContext.Current.Response.Cookies["userinfo"].Value = null;
}
context.Session["USERLOGIN"] = u;
//保存登录的user信息
addOnlineUser(u);
;
context.Response.Write("{\"error\":0,\"url\":\"missile/missile\"}");
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
搭建singnalR:
1,首页引用:
2.引用自己写的js:
/*创建signalr服务*/
var initSignalRChannel = function () {
console.log(11111111111111111111);
console.log($("#userid").val());
/*拿到与后台相关的服务*/
window.missilechat = $.connection.missileHub;
/*前台提供一个方法*/
missilechat.client.missilesoftView = function (msg) {
consolelog("后台调用前台1");
console.log(msg);
}
/*传递到hub参数集合-key,value*/
$.connection.hub.qs = {
userid: $("#userid").val()
};
/*用户登陆的方法*/
missilechat.client.onLin = function (cont) {
$("#myselect").html(cont)
}
/*启动前台的服务*/
$.connection.hub.start();
/*调用方法*/
$("#mylogin").click(function () {
window.missilechat.server.getMissileData("NAMAMA", "ASDFA", "ASDFA");
});
};
/*执行初始化方法*/
var AllfunctionRun= function() {
initSignalRChannel();
}();
3.后台处理通讯类,包括保存登陆数据,创建前后台数据发送接口:
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Missile.Action.BaseClass;
using Missile.Action.JSONTool;
using static Missile.Action.SystemObjectAction.SystemObjectAction;
using Missile.user;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using Missile.Sql.Action;
namespace not_can_fly_missile.Signalr
{
[HubName("missileHub")]
public class missileHub : Hub
{
/// <summary>
/// 连接用户集合
/// </summary>
public static List<UserInfo> ConnectUsers { get; set; }
/// <summary>
public missileHub() : base()
{
//_hubContext = GlobalHost.ConnectionManager.GetHubContext<ServerHub>();
}
/// <summary>
/// 保存客户端连接信息
/// </summary>
/// <param name="userid">USER ID</param>
/// <param name="conid">客户端ID</param>用户的在线的状态:1、在线 2、离开 3、忙碌 4、请勿打扰 0、离线
///
private void _setUserConnected(Guid userid, string conid)
{
try
{
if (ConnectUsers == null) ConnectUsers = new List<UserInfo>();
int _userindex = ConnectUsers.FindIndex(_u => _u.MU_ID.ToUpper() == userid.ToString().ToUpper());
if (_userindex < 0)
{
UserInfo ui = MissileSavUser.getUserInfo(userid.ToString());
if (ui == null) return;
ConnectUsers.Add(new UserInfo()
{
connid = conid,
MU_ID = ui.MU_ID,
MU_NAME = ui.MU_NAME,
ACCESS_TOKEN = ui.ACCESS_TOKEN,
MU_PWD = ui.MU_PWD,
MU_xm = ui.MU_xm,
OnlinTime=DateTime.Now,
LoginStatc=1,
isConnect = true
});
}
else
{
ConnectUsers[_userindex].connid = conid;
ConnectUsers[_userindex].isConnect = true;
}
}
catch (Exception ex)
{
BaseClass.MissileLog.WriteLog(ex);
}
}
/// <summary>
/// 设置用户连接(当客户端重连的时候执行)
/// 会发送用户信息、菜单、消息等基础信息
/// </summary>
/// <param name="conid">客户端ID</param>
private void _sendUserData(string conid)
{
try
{
if (ConnectUsers == null) ConnectUsers = new List<UserInfo>();
int index = ConnectUsers.FindIndex(cu => cu.connid == conid);
if (index < 0) return;
UserInfo uc = _getusercodebyconnectionid(conid);
if (uc == null) return;
DataTable dtorg = MissileSqltion.MenuList(uc.MU_ID);
DataTable dsMenues = MissileSqltion.UserListAll();
DataTable dt = new DataTable();
DataSet msegset = new DataSet();
missileHubControl.sendToJiClient(ConnectUsers.Where<UserInfo>(u => u.isConnect).ToList()
, "{\"useron\":" + JSONTool.ToJson(ConnectUsers[index]) + ",\"userlist\":"
+ JSONTool.ToJson(ConnectUsers.Where<UserInfo>(u => u.isConnect).ToList()) + "}");
}
catch (Exception ex)
{
BaseClass.MissileLog.WriteLog(ex);
}
}
/// <summary>
/// 用户离线
/// </summary>
/// <param name="conid">客户端ID</param>
private void _setUserOffline(Guid userid)
{
try
{
if (ConnectUsers == null) ConnectUsers = new List<UserInfo>();
int index = ConnectUsers.FindIndex(cu => cu.MU_ID == userid.ToString());
if (index >= 0)
{
ConnectUsers[index].isConnect = false;
ConnectUsers[index].BreakTime = DateTime.Now;
//清除用户登录信息,记录离线时间,修改登录状态
UserInfo offuser = ConnectUsers[index];
missileHubControl.sendToJiClient(ConnectUsers.Where<UserInfo>(u => u.MU_ID != userid.ToString()).ToList()
, "{\"useroff\":" + JSONTool.ToJson(offuser) + ",\"userlist\":"
+ JSONTool.ToJson(ConnectUsers.Where<UserInfo>(u => u.isConnect).ToList()) + "}");
}
}
catch (Exception ex)
{
BaseClass.MissileLog.WriteLog(ex);
}
}
/// <summary>
/// 创建数据处理接口
/// </summary>
/// <param name="voidname">标识名称==方法名</param>
/// <param name="datatype">传递的数据类型</param>
/// <param name="pares">传递的数据</param>
public void setMissileData(string voidname, string datatype, string pares)
{
//处理数据。。。。。。。
missileHubControl.sendToJiClient(u, "{\"" + datatype + "\":");//+ JSONTool.ToJson(ds) + "}");
}
/// <summary>
/// 创建数据查询接口
/// </summary>
/// <param name="voidname">标识名称==方法名</param>
/// <param name="datatype">传递的数据类型</param>
/// <param name="pares">传递的数据</param>
public void getMissileData(string voidname, string datatype, string pares)
{
//处理数据。。。。。。
missileHubControl.sendToJiClient(u, "{\"" + datatype + "\":" + "");//JSONTool.ToJson(dt) + "}");
}
/// <summary>
/// 创建数据查询接口--指定查询
/// </summary>
/// <param name="voidname"></param>
/// <param name="connectionid"></param>
/// <param name="datatype"></param>
/// <param name="para"></param>
public void getMissileData(string voidname, string datatype, string connectionid, string para)
{
Dictionary<string, object> _para = null;//JSONTool.JsonToDictionary(para);将json转化为字典类型
//获取此数据发送过来的客户端id
UserInfo u = _getusercodebyconnectionid(connectionid);
if (u == null || u.MU_ID == null) return;
DataSet dt = GetSystemObjectData(datatype, u.MU_ID, connectionid, _para);
if (dt == null || dt.Tables.Count == 0 || dt.Tables[0].Columns.Count == 0) return;
missileHubControl.sendToJiClient(u, "{\"" + datatype + "\":" + "");//JSONTool.ToJson(dt) + "}");
}
/// <summary>
/// 根据客户端ID查询userinfo
/// </summary>
/// <param name="connid">客户端ID</param>
/// <returns>包含数据的userinfo集合</returns>
private UserInfo _getusercodebyconnectionid(string connid)
{
return ConnectUsers.SingleOrDefault<UserInfo>(t => t.connid == connid);
}
//**************************链接事件****************************//
/// <summary>
/// 客户端连接上时,会进入到此方法中
/// </summary>
/// <returns></returns>
public override Task OnConnected()
{
try
{
//获取连接成功的用户id
Guid userid = Guid.Empty;
if (Guid.TryParse(Context.QueryString["userid"], out userid))
//保存连接信息
_setUserConnected(userid, Context.ConnectionId);
}
catch (Exception ex)
{
BaseClass.MissileLog.WriteLog(ex);
}
return base.OnConnected();
}
/// <summary>
/// 客户端重新连接,会进入到此方法中
/// </summary>
/// <returns></returns>
public override Task OnReconnected()
{
//获取连接成功的用户id
Guid userid = Guid.Empty;
if (Guid.TryParse(Context.QueryString["userid"], out userid))
//保存连接信息
_setUserConnected(userid, Context.ConnectionId);
return base.OnReconnected();
}
/// <summary>
/// 客户端断开链接,会进入到此方法中
/// </summary>
/// <param name="stopCalled"></param>
/// <returns></returns>
public override Task OnDisconnected(bool stopCalled)
{
Guid userid = Guid.Empty;
if (Guid.TryParse(Context.Request.QueryString["userid"], out userid))
_setUserOffline(userid);
return base.OnDisconnected(stopCalled);
}
//***********************end *********************************//
}
/// <summary>
/// 发送数据,调用前台类
/// 前台方法missilesoftView
/// </summary>
public class missileHubControl
{
/// <summary>
/// 定义静态的hub
/// </summary>
private static IHubContext _missileHub
{
get { return GlobalHost.ConnectionManager.GetHubContext("missileHub"); }
}
/// <summary>
/// 根据用户编号单个对象发送数据
/// </summary>
/// <param name="usercode">usercode用户编号</param>
/// <param name="jsondata">json数据</param>
public static void sendToJiClient(string usercode, string jsondata)
{
UserInfo _cucon = missileHub.ConnectUsers.Where(u => u.MU_ID == usercode).ToList<UserInfo>().FirstOrDefault();
sendToJiClient(_cucon, jsondata);
}
/// <summary>
/// 群发发送数据-list
/// </summary>
/// <param name="_cucon">list数组类型发送-群发接口--list</param>
/// <param name="jsondata">json数据</param>
public static void sendToJiClient(List<UserInfo> _cucon, string jsondata)
{
try
{
List<string> conids = new List<string>();
foreach (UserInfo jcu in _cucon)
{
conids.Add(jcu.connid);
}
_missileHub.Clients.Clients(conids).missilesoftView(jsondata);
}
catch (Exception ex)
{
//记录日志
BaseClass.MissileLog.WriteLog(ex);
}
}
/// <summary>
/// class 封装对象发送数据
/// </summary>
/// <param name="user">userinfo</param>
/// <param name="jsondata">json数据</param>
public static void sendToJiClient(UserInfo user, string jsondata)
{
try
{
List<string> conids = new List<string>();
conids.Add(user.connid);
_missileHub.Clients.Clients(conids).missilesoftView(jsondata);
}
catch (Exception ex)
{
//记录日志
BaseClass.MissileLog.WriteLog(ex);
}
}
}
}
4.登陆时保存的用户信息,用于登陆后传递回singnalr类处理后调用获取用户数据:
using Missile.user;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace not_can_fly_missile.Signalr
{
public class MissileSavUser
{
//登录成功储存的用户信息
private static Dictionary<string, object> MissileSavUserdic = new Dictionary<string, object>();
public static string USERONLINE = "ONLINEUSERS";
public static void addCache(string key, object val)
{
try
{
if (MissileSavUserdic.ContainsKey(key))
MissileSavUserdic[key] = val;
else
MissileSavUserdic.Add(key, val);
}
catch (Exception ex)
{
//BaseClass.doLogBack(ex.Message);
//BaseClass.doLogBack(ex.StackTrace);
}
}
/// <summary>
/// 判断Dictionary中是否存在key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static object getCache(string key)
{
return MissileSavUserdic.ContainsKey(key) ? MissileSavUserdic[key] : null;
}
/// <summary>
///判断用户的登录信息是否已经保存
/// </summary>
/// <param name="userid"></param>
/// <returns></returns>
public static UserInfo getUserInfo(string userid)
{
try
{
//获取保存的list
object o = getCache(USERONLINE);
//判断是否为空以及是否存在该条目
if (o == null || ((List<UserInfo>)o).Count == 0 || ((List<UserInfo>)o).Find(cu => cu.MU_ID.ToUpper() == userid.ToUpper()) == null) return null;
//强制转换
List<UserInfo> uc = (List<UserInfo>)o;
//返回唯一满足条件的一条数据
return uc.Single<UserInfo>(u => u.MU_ID.ToUpper() == userid.ToUpper());
}
catch (Exception ex)
{
//记录日志
return null;
}
}
/// <summary>
/// 保存添加登录信息
/// 未添加返回null 添加成功返回其本身u
/// </summary>
/// <param name="u">登录信息类</param>
/// <returns></returns>
public static UserInfo addOnlineUser(UserInfo u)
{
try
{
//验证传递过来的u是否为空
if (u == null) return null;
UserInfo ut = getUserInfo(u.MU_ID);
//获取该数据是否保存过
if (ut!= null) return null;
object o = getCache(USERONLINE);
List<UserInfo> uc = new List<UserInfo>();
if (o != null) uc = (List<UserInfo>)o;
uc.Add(u);
addCache(USERONLINE, uc);
return u;
}
catch (Exception ex)
{
return null;
}
}
}
}
5,加上傲大大 的启动类:
using Owin;
using Microsoft.Owin;
[assembly: OwinStartupAttribute(typeof(Microsoft.AspNet.SignalR.StockTicker.Startup), "Configuration")]
namespace Microsoft.AspNet.SignalR.StockTicker
{
public static class Startup
{
public static void ConfigureSignalR(IAppBuilder app)
{
app.MapSignalR();
}
public static void Configuration(IAppBuilder app)
{
Microsoft.AspNet.SignalR.StockTicker.Startup.ConfigureSignalR(app);
}
}
}
6.前台接收singnalr发送回来的json数据包,经过处理后动态加载页面用:
/*对返回的数据进行统一处理*/
var updateVVModule = function (data) {
require(["layer"], function () {
layer.closeAll('loading');
$.each(JSON.parse(data), function (k, v) {
if (v == undefined) { layer.alert("获取数据过程中出现错误。"); return; }
if (v.SystemError != undefined && v.SystemError.length > 0 && new Number(v.SystemError[0].errorcode) > 0) {
layer.alert(v.SystemError[0].message);
return;
}
/*执行取回数据的类型的方法*/
if (eval("typeof(" + k + ")") == "function") {
eval(k + "(" + JSON.stringify(v) + ");");
}
});
});
};
2与6的js是一个js:
返回回来的数据通过knockout.js监控属性来处理,如果有其他js有监控数据的方法也可以。
其中的写入数据库查询数据库的方法未贴出。。。。。。。。。。:
为粘贴出的内容: