一、新建项目,选MVC项目默认 添加mvc文件夹和核心引用
二、添加SignaIR包
SignalR的准备:NuGet包管理器搜索:工具——>库程序包管理器——>Microsoft.AspNet.SignalR 或者 工具——>库程序包管理器——>程序包管理器控制台 Install-Package Microsoft.AspNet.SignalR。
三、新建startup文件(在App_Start目录内),用来启动SignalR
选择常规-->选择OWIN Startup类-->修改名字: Startup.cs
using Microsoft.Owin; using Owin; using System; using System.Collections.Generic; using System.Linq; using System.Web; [assembly: OwinStartup(typeof(demo2.App_Start.Startup))] namespace demo2.App_Start { public class Startup { public void Configuration(IAppBuilder app) { // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888 app.MapSignalR(); } } }
项目外ServerHub.cs文件
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.AspNet.SignalR; namespace ChatSignalR { public class ServerHub : Hub { public void SendMsg(string message) { //调用所有客户端的sendMessage方法 Clients.All.sendMessage(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), message); } } }
四、客户端代码
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script src="~/scripts/jquery-1.6.4.min.js"></script> <!--引用SignalR库. --> <script src="~/scripts/jquery.signalR-2.3.0.min.js"></script> <!--引用自动生成的SignalR 集线器(Hub)脚本.在运行的时候在浏览器的Source下可看到 <script src="~/signalr/hubs"></script>这个js。这是在项目中找不到,是有signalr自己生成作为桥接的js。引入最重要的hubs js,这个js其实并不存在,SignalR会反射获取所有供客户端调用的方法放入hubs js中--> <script src="~/signalr/hubs"></script> </head> <body> <div> <div class="container"> <input type="text" id="message" /> <input type="button" id="sendmessage" value="Send" /> <input type="hidden" id="displayname" /> <ul id="messageBox"></ul> </div> </div> </body> <script> $(function () { //引用自动生成的集线器代理 var chat = $.connection.serverHub; //定义服务器调用的客户端sendMessage来显示新消息 chat.client.sendMessage = function (name, message) { //向页面添加消息 $("#messageBox").append('<li><strong style="color:green">'+htmlEncode(name)+'</strong>:'+htmlEncode(message)+'</li>'); } //设置焦点到输入框 $('#message').focus(); //开始连接服务器 $.connection.hub.start().done(function () { $('#sendmessage').click(function () { //调用服务器端集线器的Send方法 chat.server.sendMsg($('#message').val()); //清空输入框信息并获取焦点 $("#message").val('').focus(); }) }) }); //为显示的消息进行html编码 function htmlEncode(value) { var encodeValue = $('<div/>').text(value).html(); return encodeValue; } </script> </html>
扩展 App_Start文件夹内启动文件不变,集线器操作类,实现控制器内发送
1、新建login控制器如下
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace ChatSignalR.Controllers { public class LoginController : Controller { // GET: Login public ActionResult Index() { // 判断是否是新用户 if (Request.Cookies["USERNAME"] != null) //如果是新用户,则跳转到新用户页面 { return RedirectToAction("Index", "Index"); } //iewBag.UserName = HttpUtility.UrlDecode(cookieUserName.Value); return View(); } [HttpPost] public ActionResult Login(FormCollection fc) { string userName = fc["uid"]; Response.Cookies.Add(new HttpCookie("USERNAME", HttpUtility.UrlEncode(userName))); return RedirectToAction("Index", "Index"); } } }
View:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script src="~/scripts/jquery-1.6.4.min.js"></script> </head> <body> <div> @using (Html.BeginForm("login", "Login", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { <div class="loginBox"> <div class="loginBoxCenter"> <p><input type="text" id="uid" name="uid" class="loginInput" required="required" placeholder="请输入用户名" value="" /></p> </div> <div class="loginBoxButtons"> <button class="loginBtn">登录</button> </div> </div> } </div> <script type="text/javascript"> $(function () { }); </script> </body> </html>
1、新建Index控制器如下
public class IndexController : Controller { /// <summary> /// Clients,用来主动发送消息 /// </summary> /// // GET: Index public ActionResult Index() { ViewBag.hard_value = new List<SelectListItem>() { new SelectListItem(){Value="0",Text="xpy0928"}, new SelectListItem(){Value="1",Text="cnblogs"} }; return View(); } [HttpPost] public ActionResult ClearCookIe() { HttpCookie cookies = Request.Cookies["USERNAME"]; //一定要注意设置Cookies是用Response读取是用Request两者不一样! if (cookies != null) { cookies.Expires = DateTime.Today.AddDays(-1); Response.Cookies.Add(cookies); Request.Cookies.Remove("USERNAME"); } if (Request.Cookies["USERNAME"] == null) { return Content("/Login/Index"); } else { return Content("fail"); } } [HttpPost] public ActionResult SendSystemMsg() { //从外部访问类访问服务器上相对应的hub服务方式 var hub = GlobalHost.ConnectionManager.GetHubContext<ServerHub>(); //在集线器外部推送消息 //hub.Clients.All.notice("都起来吃饭了"); hub.Clients.All.sendMessage(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "都起来吃饭了"); if (1 == null) { return Content("ok"); } else { return Content("fail"); } } /* //从外部访问持久性连接服务 方式 var connectionContext = GlobalHost.ConnectionManager.GetConnectionContext<TestConnection>();//管理相对应的持久性连接 connectionContext.Connection.Broadcast("该吃饭了");//向所有已连接的客户端发送信息 */ }
View
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script src="~/scripts/jquery-1.6.4.min.js"></script> <!--引用SignalR库. --> <script src="~/scripts/jquery.signalR-2.3.0.min.js"></script> <!--引用自动生成的SignalR 集线器(Hub)脚本.在运行的时候在浏览器的Source下可看到 <script src="~/signalr/hubs"></script>这个js。这是在项目中找不到,是有signalr自己生成作为桥接的js。引入最重要的hubs js,这个js其实并不存在,SignalR会反射获取所有供客户端调用的方法放入hubs js中--> <script src="~/signalr/hubs"></script> </head> <body> <div> @Html.DropDownList("hard-code-dropdownlist", new SelectList(ViewBag.hard_value, "Value", "Text"), new { @class = "btn btn-success dropdown-toggle form-control" }) <div class="container"> <input type="text" id="message" /> <input type="button" id="sendmessage" value="Send" /> <input type="hidden" id="displayname" /> <ul id="messageBox"></ul> </div> <input type="button" id="clearcookie" value="清楚cookie" /> <input type="button" id="SendSystemMsg" value="发送系统消息" /> </div> </body> <script type="text/javascript"> $(function () { //引用自动生成的集线器代理 var chat = $.connection.chatHub; //定义服务器调用的客户端sendMessage来显示新消息 chat.client.sendMessage = function (name, message) { //向页面添加消息 $("#messageBox").append('<li><strong style="color:green">'+htmlEncode(name)+'</strong>:'+htmlEncode(message)+'</li>'); } //设置焦点到输入框 $('#message').focus(); //开始连接服务器 $.connection.hub.start().done(function () { // 连接成功时 $('#sendmessage').click(function () { //调用服务器端集线器的Send方法 chat.server.sendMsg($('#message').val()); //清空输入框信息并获取焦点 $("#message").val('').focus(); }) }).fail(function (res) { // 连接失败时 }); }); $("#clearcookie").click(function () { $.ajax({ url: '/Index/ClearCookIe', type:'post', //dataType:'json', timeout:1000, success: function (data, status) { if(data=="fail") console.log(data) else location.href = data; }, fail: function (err, status) { console.log(err) } }); }) $("#SendSystemMsg").click(function () { $.ajax({ url: '/Index/SendSystemMsg', type: 'post', //dataType:'json', timeout: 1000, success: function (data, status) { console.log(data) }, fail: function (err, status) { console.log(err) } }); }) //为显示的消息进行html编码 function htmlEncode(value) { var encodeValue = $('<div/>').text(value).html(); return encodeValue; } </script> </html>
另外集线器代码也更改--我放入HubignaIR文件夹内
using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using System.Web; namespace demo2.HubignaIR { [HubName("chatHub")] // using Microsoft.AspNet.SignalR.Hubs; // 标记名称供js调用 public class ServerHub : Hub { public void SendMsg(string message) { //调用所有客户端的sendMessage方法 Clients.All.sendMessage(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), message); // 获取链接id var connectionId = Context.ConnectionId; // 获取cookie var cookie = HttpUtility.UrlDecode(Context.RequestCookies.ToString()); } /// <summary> /// 客户端连接的时候调用 /// </summary> /// <returns></returns> public override Task OnConnected() { Trace.WriteLine("客户端连接成功"); return base.OnConnected(); } private string UserName { get { var userName = Context.RequestCookies["USERNAME"]; return userName == null ? "" : HttpUtility.UrlDecode(userName.Value); } } } }
GroupChat.cs
namespace ChatSignalR.HubSignalR { /*封装主动发送消息的单例 如果需要发送消息,直接控制器里面调用SendSystemMsg即可。 GroupChat.Instance.SendSystemMsg("消息"); */ /// <summary> /// 主动发送给用户消息,单例模式 /// </summary> public class GroupChat { /// <summary> /// Clients,用来主动发送消息 /// </summary> private IHubConnectionContext<dynamic> Clients { get; set; } private readonly static GroupChat _instance = new GroupChat(GlobalHost.ConnectionManager.GetHubContext<ServerHub>().Clients); private GroupChat(IHubConnectionContext<dynamic> clients) { Clients = clients; } public static GroupChat Instance { get { return _instance; } } /// <summary> /// 主动给所有人发送消息,系统直接调用 /// </summary> /// <param name="msg"></param> public void SendSystemMsg(string msg) { Clients.All.publshMsg(new { Name = "系统消息", Msg = msg, Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }); } } }