• SignalR


    SignalR是一个可以让服务器向客户端实时推送消息的库

    上图是他基本原理,多个客户端连接同一个服务器,当客户端A调用服务器的方法时,服务器会调用所有客户端的方法,这样客户端B和客户端C,虽然没做操作,但是依然会收到消息

    例如QQ群聊天,一个人发出一条消息,其他人都会收到这条消息

    首先要添加一个名为Startup的类(并不知道这个类是干嘛的,但我猜是注册) 

     public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.MapSignalR();
            }
        }

    然后我们开始写服务端

    服务端的类必须要继承Hub类

    public class SigHub:Hub
        {
            
        }

    然后在这个类中写一些方法,供客户端调用

    public class SigHub:Hub
        {
            public void ServerShow(string text)
            {
                Clients.All.clientShow(text);
            }
        }

    方法内的操作是调用所有客户端的clientShow方法(虽然我们客户端还没写,这个方法自然也还没有,但是不要紧,后面记得写上就行)

    到这里我们就能大致明白上面说的基本原理和图了

    一个客户端调用服务端的ServerShow方法,然后ServerShow调用所有客户端的clientShow方法

    接下来我们去写客户端

    客户端是网页,写在js中

    首先引用三个必要的js文件

    <script src="Scripts/jquery-1.6.4.js"></script>
    <script src="Scripts/jquery.signalR-2.2.2.js"></script>
    <script src="/signalr/hubs"></script>

    第三个文件是生成的,项目里看不到,总之写上就行了

    第一步 帮你的服务端类存到变量里

    注 sigHub是你服务端里写方法的类名

            var hub = $.connection.sigHub;

    然后把服务端调用的客户端方法创建出来

    hub.client.clientShow = function (date) {
                alert(date);
    }

    最后调用服务端的方法

    $.connection.hub.start().done(function () {
                hub.server.serverShow("12313");
    });

    完整代码

    <script>
            var hub = $.connection.sigHub;
            hub.client.clientShow = function (date) {
                alert(date);
            }
            $.connection.hub.start().done(function () {
                hub.server.serverShow("12313");
            });
    </script>

    SignalR有几种不同的推送方式

    Clients.Caller 推送给当前用户(大概)

    Clients.All 推送给所有用户

    Clients.Others 推送给自己以外所有的用户

    Clients.Client(connectionid) 推送给指定的用户

    Clients.Group(GroupId) 推送给指定组中的用户

    Core版本的使用

    引用core版本类库

    Install-Package Microsoft.AspNetCore.SignalR -Version 1.0.0-alpha2-final (还没有正式版)

    建立一个hub类,和framework的一样要继承于Hub

    然后对Startup进行配置

    在ConfigureServices中加上 services.AddSignalR();

    public void ConfigureServices(IServiceCollection services)
            {
               
                services.AddSignalR();
    
                //↓用来跨域的不用在意
                services.AddCors(options =>
                {
                    options.AddPolicy("any", builder =>
                    {
                        builder.AllowAnyOrigin() //允许任何来源的主机访问
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials();//指定处理cookie
                    });
                });
                services.AddMvc(); //← 本来就有的不用在意
            }            

    之后在Configure中注册我们的hub类

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                //↓本来就有
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                //↓加上才能访问wwwroot中的静态文件
                app.UseFileServer();
                //↓跨域
                app.UseCors("any");
    
                //↓注册hub
                app.UseSignalR(routes =>
                {
                    routes.MapHub<SigHub>("sigHub");
                });
    
                //↓路由设置为MVC那样
                app.UseMvcWithDefaultRoute();
                //↓本来就有
                app.UseMvc();
            }                

    这样我们的SignalR就配置好了,接下来就是如何使用

    首先是我们的hub类,变化并不是很大,但还是有不同的地方

    public void Test(string msg) 
    {
           Clients.All.test(msg); //←framework的写法
           
           Clients.All.InvokeAsync("test",msg); //←core的写法
    }    

    我把两个的写法放到一起给你们对比一下,这样更清楚变化

    framework版本是直接在后面点客户端的方法名来调用,参数也是直接放在方法的括号中就行了

    core版本的点后面则是一个固定的方法InvokeAsync

    方法的第一个参数是客户端的方法名,第二个参数是要传的参数

    如果不止一个参数的话,直接在后面继续写就行了

    Clients.All.InvokeAsync("test","参数1","参数2","参数3");

    对客户端的几种不同调用方式

    All 全部调用

    Client 调用指定的客户端

    Group 调用指定组当中的客户端

    (other不知为什么没有了)

    以上就是服务端的写法,接下来讲解客户端的写法

    客户端的变化就比较大了

    它需要引用一个名为signalr-client-1.0.0-alpha2-final的js文件

    首先要创建一个连接对象

    var transport = signalR.TransportType.LongPolling; //连接类型
    var connection = new signalR.HubConnection(`http://localhost:65449/sigHub`, { transport: transport }); //创建连接对象
    connection.start();//打开连接

    之后是注册服务端调用的客户端方法

    connection.on("test", function (msg) {
             $("ul").append("<li>" + msg + "</li>");
    });

    function中的msg就是从服务端传过来的参数

    最后是调用服务端的方法

    $("#send").click(function () {
                    var date = "abc";
                    connection.invoke("test",date); //调用服务端的Test方法
    });

    注意:即使在服务端写的方法名是开头大写的,客户端调用时也要小写

    date则是传给服务端的参数,不需要传参的话就不用写

    connection.invoke("test");

    页面的代码

    <button id="send">发送</button>
    <ul>
    
    </ul>

    完整的代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script src="jquery.js"></script>
        <script src="signalr-client-1.0.0-alpha2-final.js"></script>
        <script>
            $(function () {
                var transport = signalR.TransportType.LongPolling; //连接类型
                var connection = new signalR.HubConnection(`http://localhost:65449/sigHub`, { transport: transport }); //创建连接对象
                connection.start(); //打开连接
                
                //注册客户端方法
                connection.on("test", function (msg) {
                    $("ul").append("<li>" + msg + "</li>");
                });
                //调用服务端方法
                $("#send").click(function () {
                    var date = "abc";
                    connection.invoke("test",date);
                });
            })
            
        </script>
    </head>
    <body>
        <button id="send">发送</button>
        <ul>
    
        </ul>
    </body>
    </html>

    效果

    这就是SignalR的Core版本使用了,最后说下跨域

    SignalR的hub类可以被跨域访问,只要普通的配置一下core的api跨域就行了,这里就不说了 (其实在上面的配置中已经把跨域配置也写出来了)

  • 相关阅读:
    Model, View(Camera), Perspective (1)
    流状态和c++的异常处理
    VAO VBO EBO(3)
    VAO VBO EBO(2)
    VAO VBO EBO(1)
    函数指针(2)
    函数指针
    内联函数和宏函数的一些区别
    关于宏的一些知识
    关于未来方向
  • 原文地址:https://www.cnblogs.com/nicopoiduang/p/8047188.html
Copyright © 2020-2023  润新知