本demo是通过mvc 实现
(1)首先在App_Start下添加Startup.cs文件定义管线的启动:
using Microsoft.Owin;using Owin;[assembly: OwinStartup(typeof(SignalRTest.App_Start.Startup))]namespace SignalRTest.App_Start{ public class Startup { public void Configuration(IAppBuilder app) { // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888 //app.MapSignalR("echo/{*operation}"); app.MapSignalR(); } }}
(2)定义Hub的客户端中包括的方法
public interface IPlatHubClient { void ReceiveMsg(string message);//定义前台客户端上注册的方法 }
(3)实现Hub服务器端
首先定义Hub的注册绑定类,该类可以实现hub的clientid与sessionID、userid的绑定(按需修改使用)
public class PlatHubRegisteInfo { public string Id { get; set; } public string SessionId { get; set; } public string UserId { get; set; } }
PlatHub实现接口如下:(这是真正的通信管线,直接放到项目中即可,无需其他地方注册)
[HubName("PlatHub")] public class PlatHub : Hub{ private static readonly object ClientMapLock = new object(); public static readonly Dictionary ClientMap = new Dictionary (); /// /// 客户端注册连接信息 /// /// [HubMethodName("Registe")] public void Registe(string id) { lock (ClientMapLock) { ClientMap.Add(new PlatHubRegisteInfo { Id = id }, this.Context.ConnectionId); } Log.Write("", "Registe:ConnectionId=" + Context.ConnectionId + Environment.NewLine +"id="+ id); } public void BroadcastToAll(string message) { Clients.All.ReceiveMsg(Newtonsoft.Json.JsonConvert.SerializeObject(new { id = Context.ConnectionId, msg = message })); } public void BroadcastToSome(string[] ids, string message) { Clients.Clients(ids.ToList()).ReceiveMsg(Newtonsoft.Json.JsonConvert.SerializeObject(new { id = Context.ConnectionId, msg = message })); } // // 摘要: // Called when the connection connects to this hub instance. // // 返回结果: // A System.Threading.Tasks.Task public override async Task OnConnected() { var t = this; base.OnConnected(); return; } // // 摘要: // Called when a connection disconnects from this hub gracefully or due to a timeout. // // 参数: // stopCalled: // true, if stop was called on the client closing the connection gracefully; false, // if the connection has been lost for longer than the Microsoft.AspNet.SignalR.Configuration.IConfigurationManager.DisconnectTimeout. // Timeouts can be caused by clients reconnecting to another SignalR server in scaleout. // // 返回结果: // A System.Threading.Tasks.Task public override async Task OnDisconnected(bool stopCalled) { var t = this; var infos = ClientMap.Where(a => a.Value == this.Context.ConnectionId); if (infos.Any()) { var info = infos.First(); lock (ClientMapLock) { ClientMap.Remove(info.Key); } Log.Write("", "Disconnected:ConnectionId=" + Context.ConnectionId + Environment.NewLine + "id=" + info.Key.Id); } base.OnDisconnected(stopCalled); return; } // // 摘要: // Called when the connection reconnects to this hub instance. // // 返回结果: // A System.Threading.Tasks.Task public override async Task OnReconnected() { var t = this; base.OnReconnected(); return; } protected override async void Dispose(bool disposing) { var t = this; base.Dispose(disposing); return; } }
(3)添加控制器HomeController,并添加试图方法:
public ActionResult Index() { Guid id = Guid.NewGuid(); Response.Cookies.Add(new HttpCookie("id", id.ToString()));//cookie将通过客户端的Registe实现与服务器的关联 return View(); }
(4)前台Index试图如下:
Home Page - 我的 ASP.NET 应用程序 homemsgs:
在前端代码中,如下代码是定义客户端的方法:
chat.client.ReceiveMsg = function (message) { //var ob = $.parseJSON(message); // $("#msgContainer").append("id:" + ob.code + " msg:" + ob.content + ""); $("#msgContainer").append("" + message+""); };
前端如下代码是访问服务器:
chat.server.Registe($.cookie('id'));//Registe是PlatHub上通过特性HubMethodName定义的
前端代码调用的后端控制器GuangBo实现如下:
[HttpPost] public JsonResult GuangBo(string msg) { var chatHub = GlobalHost.ConnectionManager.GetHubContext(); chatHub.Clients.All.ReceiveMsg(msg);//给所有人 return Json(new { code = 1 }); }
若希望给单独一个ID发送,可以采用如下:
[HttpPost] public JsonResult ToSingle(string client,string msg) { var chatHub = GlobalHost.ConnectionManager.GetHubContext(); chatHub.Clients.Client(client).ReceiveMsg(msg); return Json(new { code = 1 }); }
可以通过
HubName、HubMethodName
两个特性重命名管线名称、服务器端注册的管线实现名称