您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 0浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

SignalR简介

寒冰屋 发布时间:2019-06-10 21:17:24 ,浏览量:0

目录

介绍

什么是SignalR?

连接和集线器(Hubs)

创建应用程序

添加客户端循环

添加服务器循环

向客户端添加平滑动画

参考

  • 下载源 - 5.7 MB
介绍

本技巧内容涵盖了在Web应用程序环境中使用SignalR进行实时通信的介绍性信息,其中服务器可以在客户端可用时立即将信息推送给客户端,而不是等待客户端从服务器请求数据。

SignalR对于万维网上的聊天应用程序,仪表板或游戏非常有用,但对于工业桌面应用程序也很重要。

如果您使用AJAX来提高Web应用程序的响应速度,那么SignalR是一个有用的替代方案。

您可以通过启用日志记录来确定SignalR正在使用的传输类型:

$.connection.hub.logging = true;

如果您随后在Web浏览器上打开调试工具,您将看到诸如“SignalR:Websocket opened”之类的行。

什么是SignalR?

通常,要从服务器获取更多客户端上的数据(如果已更改),则必须使用HTTP执行轮询GET,这是AJAX所做的。如果你想要任何接近实时的东西,那么你必须经常进行轮询。相反,使用SignalR,您有一个持久连接,客户端可以调用服务器,服务器可以调用客户端。

因此,SignalR是一个开发人员库,它简化了实时通信,其中服务器和客户端连接是持久的,与传统的HTTP范例不同。

如果您的计算机使用的是Windows 8或Windows Server 2012或更高版本,以及.NET Framework 4.5,那么SignalR将使用WebSocket;否则,它将使用HTML 5传输或Comet传输。

连接和集线器(Hubs)

客户端和服务器之间通信的两种模型是持久连接和集线器。

连接表示发送单一收件人、分组或广播邮件的端点。

Hub是持久连接(Persistent Connections)之上的一个层,允许您的客户端和服务器直接相互调用方法。使用.NET Remoting的.NET开发人员会熟悉此模型。这允许您传递强类型参数。

当通过通信通道发送完整对象时,它们将使用JSON进行序列化。

您可以使用Fiddler等工具监视方法调用。

创建应用程序

首先创建一个空的ASP.NET Web项目,右键单击以添加SignalR,确保您的项目针对.NET 4.5或更高版本:

选择SignalR:

或者您只需在包管理器控制台中输入:

PM> install-package Microsoft.AspNet.SignalR
PM> install-Package jQuery.UI.Combined
PM> install-Package Microsoft.Web.Infrastructure

接下来,将一个名为Startup的类添加到应用程序中,该类在应用程序启动时映射SignalR集线器:

using Microsoft.AspNet.SignalR;      
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(CodeProjectSignalRSample.Startup))]
namespace CodeProjectSignalRSample
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var hubConfiguration = new HubConfiguration();
            hubConfiguration.EnableDetailedErrors = true;        
        
            app.MapSignalR();
        }
    }
}

如果您还没有,请添加以下SignalR集线器类:

using Microsoft.AspNet.SignalR;
using Newtonsoft.Json;

namespace CodeProjectSignalRSample
{
    public class MyHub : Hub
    {
        public void UpdateModel(ShapeModel clientModel)
        {
            clientModel.LastUpdatedBy = Context.ConnectionId;
            // Update the shape model within our broadcaster
            Clients.AllExcept(clientModel.LastUpdatedBy).updateShape(clientModel);
        }
    }
    public class ShapeModel
    {
        // We declare Left and Top as lowercase with 
        // JsonProperty to sync the client and server models
        [JsonProperty("left")]
        public double Left { get; set; }
        [JsonProperty("top")]
        public double Top { get; set; }
        // We don't want the client to get the "LastUpdatedBy" property
        [JsonIgnore]
        public string LastUpdatedBy { get; set; }
    }
}

客户端可以直接调用UpdateModel方法,然后将其广播到所有连接的客户端。它使用JSON自动序列化。

现在通过向解决方案添加HTML页面来添加客户端:




    SignalR Demo
    
        #shape {
            width: 100px;
            height: 100px;
            background-color: #FF0000;
        }
    







 $(function () {
            var moveShapeHub = $.connection.myHub,
            $shape = $("#shape"),
            shapeModel = {
                left: 0,
                top: 0
            };
            MyHub.client.updateShape = function (model) {
                shapeModel = model;
                $shape.css({ left: model.left, top: model.top });
            };
            $.connection.hub.start().done(function () {
                $shape.draggable({
                    drag: function () {
                        shapeModel = $shape.offset();
                        MyHub.server.updateModel(shapeModel);
                    }
                });
            });
        });

    
    

另外,请确保您的web.config文件包含以下内容:




  
    
    
  

启动应用程序,然后将URL复制到浏览器的新实例中。尝试移动形状。

添加客户端循环

在每次鼠标移动时发送位置会产生大量网络流量,因此您可以通过将此代码放入HTML文件来限制它:




    SignalR Demo
    
        #shape {
            width: 100px;
            height: 100px;
            background-color: #FF0000;
        }
    


    
    
    
    
    
        $(function () {
            var moveShapeHub = $.connection.myHub,
                $shape = $("#shape"),
                // Send a maximum of 10 messages per second
                // (mouse movements trigger a lot of messages)
                messageFrequency = 10,
                // Determine how often to send messages in
                // time to abide by the messageFrequency
                updateRate = 1000 / messageFrequency,
                shapeModel = {
                    left: 0,
                    top: 0
                },
                moved = false;
            moveShapeHub.client.updateShape = function (model) {
                shapeModel = model;
                $shape.css({ left: model.left, top: model.top });
            };
            $.connection.hub.start().done(function () {
                $shape.draggable({
                    drag: function () {
                        shapeModel = $shape.offset();
                        moved = true;
                    }
                });
                // Start the client side server update interval
                setInterval(updateServerModel, updateRate);
            });
            function updateServerModel() {
                // Only update server if we have a new movement
                if (moved) {
                    moveShapeHub.server.updateModel(shapeModel);
                    moved = false;
                }
            }
        });
    

    
添加服务器循环

将以下代码添加到集线器还可以减少服务器端的流量:

using System;
using System.Threading;
using Microsoft.AspNet.SignalR;
using Newtonsoft.Json;

namespace CodeProjectSignalRSample
{
    public class Broadcaster
    {
        private readonly static Lazy
 _instance =
            new Lazy
(() => new Broadcaster());
        // We're going to broadcast to all clients a maximum of 25 times per second
        private readonly TimeSpan BroadcastInterval =
            TimeSpan.FromMilliseconds(40);
        private readonly IHubContext _hubContext;
        private Timer _broadcastLoop;
        private ShapeModel _model;
        private bool _modelUpdated;
        public Broadcaster()
        {
            // Save our hub context so we can easily use it 
            // to send to its connected clients
            _hubContext = GlobalHost.ConnectionManager.GetHubContext();
            _model = new ShapeModel();
            _modelUpdated = false;
            // Start the broadcast loop
            _broadcastLoop = new Timer(
                BroadcastShape,
                null,
                BroadcastInterval,
                BroadcastInterval);
        }
        public void BroadcastShape(object state)
        {
            // No need to send anything if our model hasn't changed
            if (_modelUpdated)
            {
                // This is how we can access the Clients property 
                // in a static hub method or outside of the hub entirely
                _hubContext.Clients.AllExcept(_model.LastUpdatedBy).updateShape(_model);
                _modelUpdated = false;
            }
        }
        public void UpdateShape(ShapeModel clientModel)
        {
            _model = clientModel;
            _modelUpdated = true;
        }
        public static Broadcaster Instance
        {
            get
            {
                return _instance.Value;
            }
        }
    }
    public class MyHub : Hub
    {
        private Broadcaster _broadcaster;
        public MyHub()
            : this(Broadcaster.Instance)
        {
        }

        public MyHub(Broadcaster broadcaster)
        {
            _broadcaster = broadcaster;
        }

        public void UpdateModel(ShapeModel clientModel)
        {
            clientModel.LastUpdatedBy = Context.ConnectionId;
            // Update the shape model within our broadcaster
            Clients.AllExcept(clientModel.LastUpdatedBy).updateShape(clientModel);
        }
    }
    public class ShapeModel
    {
        // We declare Left and Top as lowercase with 
        // JsonProperty to sync the client and server models
        [JsonProperty("left")]
        public double Left { get; set; }
        [JsonProperty("top")]
        public double Top { get; set; }
        // We don't want the client to get the "LastUpdatedBy" property
        [JsonIgnore]
        public string LastUpdatedBy { get; set; }
    }
}
向客户端添加平滑动画

添加以下代码以使形状在1000毫秒的过程中从旧位置移动到新位置:




    SignalR Demo
    
        #shape {
            width: 100px;
            height: 100px;
            background-color: #FF0000;
        }
    


    
    
    
    
    
        $(function () {
            var moveShapeHub = $.connection.myHub,
                $shape = $("#shape"),
                // Send a maximum of 10 messages per second
                // (mouse movements trigger a lot of messages)
                messageFrequency = 10,
                // Determine how often to send messages in
                // time to abide by the messageFrequency
                updateRate = 1000 / messageFrequency,
                shapeModel = {
                    left: 0,
                    top: 0
                },
                moved = false;
            moveShapeHub.client.updateShape = function (model) {
                shapeModel = model;
                $shape.css({ left: model.left, top: model.top });
            };
            $.connection.hub.start().done(function () {
                $shape.draggable({
                    drag: function () {
                        shapeModel = $shape.offset();
                        moved = true;
                        moveShapeHub.client.updateShape = function (model) {
                            shapeModel = model;
                            // Gradually move the shape towards the new location (interpolate)
                            // The updateRate is used as the duration because by the time 
                            // we get to the next location we want to be at the "last" location
                            // We also clear the animation queue so that we start a new 
                            // animation and don't lag behind.
                            $shape.animate(shapeModel, { duration: updateRate, queue: false });
                    }
                });
                // Start the client side server update interval
                setInterval(updateServerModel, updateRate);
            });
            function updateServerModel() {
                // Only update server if we have a new movement
                if (moved) {
                    moveShapeHub.server.updateModel(shapeModel);
                    moved = false;
                }
            }
        });
    

    
参考
  • Learn About ASP.NET SignalR
  • Sample SignalR Game ShootR
  • SignalR Source Code
  • Building Web Apps with ASP.NET Jump Start: (08) Real-time Communication with SignalR
  • OWIN and Katana
  • ASP.NET SignalR Hubs API Guide - JavaScript Client

 

原文地址:https://www.codeproject.com/Tips/880963/Introduction-to-SignalR

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.2478s