SignalR 简易聊天室+SignalR如何跨域

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

环境:VS2012或以上,Frm版本4.5或以上,我用的是4.5.2

1、在 Visual Studio 中,创建一个 ASP.NET MVC Web 应用程序。

2、右键项目,添加hub类,并命名为:ChatHub【添加后,项目会自动引用SignalR的相关DLL程序集及会在Scripts文件中生成SignalR客户端JS文件】

SignalR 简易聊天室+SignalR如何跨域

JS如下:

SignalR 简易聊天室+SignalR如何跨域

 ChatHub 类的代码如下

SignalR 简易聊天室+SignalR如何跨域
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的类,如下:

SignalR 简易聊天室+SignalR如何跨域
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 页",如下:

SignalR 简易聊天室+SignalR如何跨域
<!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>:&nbsp;&nbsp;' + 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如何跨域

 聊天内容虽说不那么好吧,但我们对SignalR如何实现跨域还是非常认真的,那么怎么操作才可以跨域通信呢?

要实现SigNalR跨域,首选我们需要安装一个包,执行如下命令:

Install-Package Microsoft.Owin.Cors

然后修改我们的Startup类,如下:

SignalR 简易聊天室+SignalR如何跨域
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

首先把你的项目复制一个副本出来,放到其他文件夹中,然后修改你复制项目的运行端口号,如下:

SignalR 简易聊天室+SignalR如何跨域

最后,客户端动态引用指定URL及端口号的signalR,修改副本HTML如下:

SignalR 简易聊天室+SignalR如何跨域
<!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>:&nbsp;&nbsp;' + 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

变更点:

SignalR 简易聊天室+SignalR如何跨域

 这样就可以跨域了,下面我们来模拟下跨域的请求,如下:

 1、启动并调试服务端项目,端口为:44330,并把chathub所有方法都打上断点,

/2、启动不调试你的副本项目,端口为:44333,我们通过观察断点是否能进入判断跨域请求是否成功

SignalR 简易聊天室+SignalR如何跨域

 

 证明跨域访问成功。

聊天内容如下:

SignalR 简易聊天室+SignalR如何跨域

参考文献:

https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/getting-started/introduction-to-signalr

https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client

https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr

https://blog.csdn.net/tte_w/article/details/80881060

上一篇:Text classification with TensorFlow Hub: Movie reviews


下一篇:HDU 3920Clear All of Them I(状压DP)