十年河东,十年河西,莫欺少年穷
学无止境,精益求精
环境:VS2012或以上,Frm版本4.5或以上,我用的是4.5.2
1、在 Visual Studio 中,创建一个 ASP.NET MVC Web 应用程序。
2、右键项目,添加hub类,并命名为:ChatHub【添加后,项目会自动引用SignalR的相关DLL程序集及会在Scripts文件中生成SignalR客户端JS文件】
JS如下:
ChatHub 类的代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.AspNet.SignalR; using System.Threading.Tasks; namespace SignalRTx.ChatHubServer { public class ChatHub : Hub { public static List<string> Connectedlst = new List<string>(); /// <summary> /// 当客户端连接时 /// </summary> /// <returns></returns> public override Task OnConnected() { var ConnectionId = Context.ConnectionId; Connectedlst.Add(ConnectionId); return base.OnConnected(); } /// <summary> /// 当客户端断开连接时,例如用户关闭页面,刷新页面 /// </summary> /// <param name="stopCalled"></param> /// <returns></returns> public override Task OnDisconnected(bool stopCalled) { var ConnectionId = Context.ConnectionId; Connectedlst.Remove(ConnectionId); return base.OnDisconnected(stopCalled); } /// <summary> /// 当客户端重连时 /// </summary> /// <returns></returns> public override Task OnReconnected() { var ConnectionId = Context.ConnectionId; if (!Connectedlst.Contains(ConnectionId)) { Connectedlst.Add(ConnectionId); } return base.OnReconnected(); } /// <summary> /// 这是一组广播消息 所有客户端均可收到此消息 /// broadcastMessage 是客户端的一个JS方法,也是回调函数,用于更新客户端 /// send 则是服务端的方法,用于客户端调用 /// </summary> /// <param name="name"></param> /// <param name="message"></param> public void Send(string name, string message) { Clients.All.broadcastMessage(name, message); } } }View Code
在项目中添加命名为Startup的类,如下:
using System; using Microsoft.AspNet.SignalR; using Microsoft.Owin; using Microsoft.Owin.Cors; using Owin; [assembly: OwinStartup(typeof(SignalRTx.ChatHubServer.Startup))] namespace SignalRTx.ChatHubServer { public class Startup { public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here app.MapSignalR(); } } }View Code
在解决方案资源管理器中,右键单击项目,然后选择 "添加 > " HTML 页",如下:
<!DOCTYPE html> <html> <head> <title>SignalR Simple Chat</title> <style type="text/css"> .container { background-color: #99CCFF; border: thick solid #808080; padding: 20px; margin: 20px; } </style> </head> <body> <div class="container"> <input type="text" id="message" /> <input type="button" id="sendmessage" value="Send" /> <input type="hidden" id="displayname" /> <ul id="discussion"> </ul> </div> <!--Script references. --> <!--Reference the jQuery library. --> <script src="Scripts/jquery-3.4.1.js"></script> <!--Reference the SignalR library. --> <script src="Scripts/jquery.signalR-2.2.2.js"></script> <!--Reference the autogenerated SignalR hub script. --> <script src="signalr/hubs"></script> <!--Add script to update the page and send messages.--> <script type="text/javascript"> $(function () { // Declare a proxy to reference the hub. var chat = $.connection.chatHub; // Create a function that the hub can call to broadcast messages. chat.client.broadcastMessage = function (name, message) { // Html encode display name and message. var encodedName = $('<div />').text(name).html(); var encodedMsg = $('<div />').text(message).html(); // Add the message to the page. $('#discussion').append('<li><strong>' + encodedName + '</strong>: ' + encodedMsg + '</li>'); }; // Get the user name and store it to prepend to messages. $('#displayname').val(prompt('Enter your name:', '')); // Set initial focus to message input box. $('#message').focus(); // Start the connection. $.connection.hub.start().done(function () { $('#sendmessage').click(function () { // Call the Send method on the hub.【服务端方法:send】 chat.server.send($('#displayname').val(), $('#message').val()); // Clear text box and reset focus for next comment. $('#message').val('').focus(); }); }); }); </script> </body> </html>View Code
运行这个HTML页面,效果如下:
聊天内容虽说不那么好吧,但我们对SignalR如何实现跨域还是非常认真的,那么怎么操作才可以跨域通信呢?
要实现SigNalR跨域,首选我们需要安装一个包,执行如下命令:
Install-Package Microsoft.Owin.Cors
然后修改我们的Startup类,如下:
using System; using Microsoft.AspNet.SignalR; using Microsoft.Owin; using Microsoft.Owin.Cors; using Owin; [assembly: OwinStartup(typeof(SignalRTx.ChatHubServer.Startup))] namespace SignalRTx.ChatHubServer { //public class Startup //{ // public void Configuration(IAppBuilder app) // { // // Any connection or hub wire up and configuration should go here // app.MapSignalR(); // } //} public class Startup { public void Configuration(IAppBuilder app) { // Branch the pipeline here for requests that start with "/signalr" app.Map("/signalr", map => { // Setup the CORS middleware to run before SignalR. // By default this will allow all origins. You can // configure the set of origins and/or http verbs by // providing a cors options with a different policy. map.UseCors(CorsOptions.AllowAll); var hubConfiguration = new HubConfiguration { //You can enable JSONP by uncommenting line below. //JSONP requests are insecure but some older browsers (and some //versions of IE) require JSONP to work cross domain EnableJSONP = true }; // Run the SignalR pipeline. We're not using MapSignalR // since this branch already runs under the "/signalr" // path. map.RunSignalR(hubConfiguration); }); } } }View Code
首先把你的项目复制一个副本出来,放到其他文件夹中,然后修改你复制项目的运行端口号,如下:
最后,客户端动态引用指定URL及端口号的signalR,修改副本HTML如下:
<!DOCTYPE html> <html> <head> <title>SignalR Simple Chat</title> <style type="text/css"> .container { background-color: #99CCFF; border: thick solid #808080; padding: 20px; margin: 20px; } </style> </head> <body> <div class="container"> <input type="text" id="message" /> <input type="button" id="sendmessage" value="Send" /> <input type="hidden" id="displayname" /> <ul id="discussion"> </ul> </div> <!--Script references. --> <!--Reference the jQuery library. --> <script src="Scripts/jquery-3.4.1.js"></script> <!--Reference the SignalR library. --> <script src="Scripts/jquery.signalR-2.2.2.js"></script> <!--Reference the autogenerated SignalR hub script. --> <script src="https://localhost:44330/signalr/hubs"></script> <!--Add script to update the page and send messages.--> <script type="text/javascript"> $(function () { // Declare a proxy to reference the hub. var chat = $.connection.chatHub; chat.connection.url = "https://localhost:44330/signalr"; // Create a function that the hub can call to broadcast messages. chat.client.broadcastMessage = function (name, message) { // Html encode display name and message. var encodedName = $('<div />').text(name).html(); var encodedMsg = $('<div />').text(message).html(); // Add the message to the page. $('#discussion').append('<li><strong>' + encodedName + '</strong>: ' + encodedMsg + '</li>'); }; // Get the user name and store it to prepend to messages. $('#displayname').val(prompt('Enter your name:', '')); // Set initial focus to message input box. $('#message').focus(); // Start the connection. $.connection.hub.start().done(function () { $('#sendmessage').click(function () { // Call the Send method on the hub.【服务端方法:send】 chat.server.send($('#displayname').val(), $('#message').val()); // Clear text box and reset focus for next comment. $('#message').val('').focus(); }); }); }); </script> </body> </html>View Code
变更点:
这样就可以跨域了,下面我们来模拟下跨域的请求,如下:
1、启动并调试服务端项目,端口为:44330,并把chathub所有方法都打上断点,
/2、启动不调试你的副本项目,端口为:44333,我们通过观察断点是否能进入判断跨域请求是否成功
证明跨域访问成功。
聊天内容如下:
参考文献:
https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/getting-started/introduction-to-signalr
https://blog.csdn.net/tte_w/article/details/80881060