zoukankan      html  css  js  c++  java
  • SignalR--Web客户端

    这里说web客户端其实是JavaScript起的作用,也可以说是JavaScript客户端。

    官方的标题的JavaScript客户端。

    下面的翻译,同样的代码的形式上传。

    PRCs  远程服务调用
    
    使用客户端的hub的代理proxy可以调用服务端的方法。
    服务端
    public class ContosoChatHub : Hub
    {
        public void NewContosoChatMessage(string name, string message)
        {
            Clients.All.addContosoChatMessageToPage(name, message);
        }
    }
    客户端(通过代理)
    var contosoChatHubProxy = $.connection.contosoChatHub;
    contosoChatHubProxy.client.addContosoChatMessageToPage = function (name, message) {
        console.log(name + ' ' + message);
    };
    $.connection.hub.start().done(function () {
        // Wire up Send button to call NewContosoChatMessage on the server.
        $('#newContosoChatMessage').click(function () {
             contosoChatHubProxy.server.newContosoChatMessage($('#displayname').val(), $('#message').val());
             $('#message').val('').focus();
         });
    });
    通过$.connection.contosoChatHub;直接拿到hub代理。
    客户端(没有代理)
    var connection = $.hubConnection();
    var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
    contosoChatHubProxy.on('addContosoChatMessageToPage', function(name, message) {
        console.log(name + ' ' + message);
    });
    connection.start().done(function() {
        // Wire up Send button to call NewContosoChatMessage on the server.
        $('#newContosoChatMessage').click(function () {
            contosoChatHubProxy.invoke('newContosoChatMessage', $('#displayname').val(), $('#message').val());
            $('#message').val('').focus();
                    });
        });
    先通过var connection=$.connection拿到hub连接,在通过这个连接创建代理connection.createHubProxy("contosoChatHub");其中contosoProxy为hub类的名字。
    
    如果你要为服务端调用创建多个事件处理程序,则不能使用生成的代理。
    否则你可以选择去使用代理而不基于你代码的引入,如果你选择不去使用代理,
    你不需要引入"/signalr/hubs"这个URL。
    
    客户端安装
    JavaScript客户端要引入JQuery和核心SignalR的js文件。JQuery文件必须在1.64版本以上,
    如果需要使用代理需要引入生成SignalR代理的js文件。
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery.signalR-2.1.0.min.js"></script>
    <script src="signalr/hubs"></script>
    最后这个js文件是动态生成的,而不是物理路径。
    这个引入顺序是固定的。
    
    html引入
    <script src="~/signalr/hubs"></script>
    
    cshtml引入
    <script src="@Url.Content("~/signalr/hubs")"></script>
    
    aspx
    <script src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script>
    
    
    如何为SignalR生成的代理创建物理路径
    作为动态生成代理的替代方法,可以创建一个物理路径来保存,
    要创建代理文件,请执行以下步骤:
    1.安装Microsoft.AspNet.SignalR.Utils.
    2.打开命令提示符并浏览到SignalR.exe文件的tools文件夹中,
    tools文件夹位于[your solution folder]packagesMicrosoft.AspNet.SignalR.Utils.2.1.0	ools
    3.输入命令
    signalr ghp /path:[path to the .dll that contains your Hub class]
    .dll文件通常是项目文件夹中的bin文件夹。
    上面的命令创建一个名为server.js的文件在server.exe的同一个文件夹啊中。
    
    
    如何建立连接
    建立连接(生成代理)
    var contosoChatHubProxy = $.connection.contosoChatHub;
    contosoChatHubProxy.client.addContosoChatMessageToPage = function (name, message) {
        console.log(userName + ' ' + message);
    };
    $.connection.hub.start()
        .done(function(){ console.log('Now connected, connection ID=' + $.connection.hub.id); })
        .fail(function(){ console.log('Could not Connect!'); });
    });
    建立?连接(不生成代理)
    var connection = $.hubConnection();
    var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
    contosoChatHubProxy.on('addContosoChatMessageToPage', function(userName, message) {
        console.log(userName + ' ' + message);
    });
    connection.start()
        .done(function(){ console.log('Now connected, connection ID=' + connection.id); })
        .fail(function(){ console.log('Could not connect'); });
    通过on创建客户端方法。
    
    默认情况下,hub的位置是当前服务,如果想连接不同的hub服务,需要在start方法之前引入。
    $.connection.hub.url="<yourbackenurl>";
    
    $.connection.hub和$.hubConnection()创建的是同一个对象
    前者引入连接对象,后者调用获得的对象。
    
    
    start是一个异步方法
    它返回的是一个jQuery Deferred 对象,所以可以添加回调函数,
    其中done是建立连接后的回调函数,同时还有fail、pipe。
    
    
    如何建立跨越
    通常,如果浏览器加载一个页面http://contoso.com,则SignalR连接位于
    http://contoso.com/signalr。如果页面http://contoso.com连接到http://consoto.com/signalr,
    这就是跨越,默认情况下,跨域是禁止的。
    
    在SignalR 1.x 中,跨域请求由单个EnableCrossDomain标记控制。此标志控制JSONP和CORS请求。
    为了更大的灵活性,所有的CORS支持已经从SignalR的服务器组建中删(如果检测到浏览器支持,
    则JavaScript客户端仍然正常使用CORS),并且已经提供了新的OWIN中间件来支持这些方案。
    
    需要通过EnableJSON在HubConfiguration对象上进行设置来明确的启用。
    1.引入Microsoft.Owin.Cors.
    2.调用UseCors。
    
    以下例子的在SignalR中实现跨域连接
    启用Cors或JSONP,使用Map和RunSignalR而不是MapSignalR。
    using Microsoft.AspNet.SignalR;
    using Microsoft.Owin.Cors;
    using Owin;
    namespace MyWebApplication
    {
        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);
                });
            }
        }
    }
    
    
    
    添加连接字符串
    可以在连接Hub时传递数据,要定义在statr方法之前。
    
    $.connection.hub.qs = { 'version' : '1.0' };生成代理
    
    var connection=$.hubConnection();
    connection.qs={'version','1.0'};不生成代理
    
    服务端读取连接字符串
    public class ContosoChatHub : Hub
    {
        public override Task OnConnected()
        {
            var version = Context.QueryString['version'];
            if (version != '1.0')
            {
                Clients.Caller.notifyWrongVersion();
            }
            return base.OnConnected();
        }
    }
    
    
    
    定义传输方法
    服务端会用最好的方法,也可以指定传输方法,在start方法之前。
    同时可以定义多个传输方式。
    
    $.connection.hub.start( { transport: ['webSockets', 'longPolling'] });
    $.connection.hub.start( { transport: 'longPolling' });生成代理
    
    var connection = $.hubConnection();
    connection.start({ transport: ['webSockets', 'longPolling'] });
    var connection =$.hubConnection();
    connection.start({transport:'longPolling'});不生成代理
    
    其中传输方法有:webSockets、foreverFrame、serverSentEvent、longPolling。
    
    获取传输名字
    $.connection.hub.start().done(function () {
        console.log("Connected, transport = " + $.connection.hub.transport.name);
    });
    
    var connection = $.hubConnection();
    connection.hub.start().done(function () {
        console.log("Connected, transport = " + connection.transport.name);
    });
    
    
    
    如何获得Hub的代理
    客户端代理的名字遵循驼峰命名发(首字母小写),SignalR会自动匹配。
    
    服务端
    public class ContosoChatHub : Hub
    
    客户端
    var myHubProxy = $.connection.contosoChatHub;
    
    var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
    
    改变Hub的名字
    通过[hubName("MyChatHub")],这时候客户端将不再匹配驼峰命名法。
    
    
    
    
    如何定义客户端方法让服务端调用
    方法名对大小写不敏感,定义在start方法之前。使用client这个属性。
    
    
    客户端
    var contosoChatHubProxy = $.connection.contosoChatHub;
    contosoChatHubProxy.client.addContosoChatMessageToPage = function (userName, message) {
        console.log(userName + ' ' + message);
    };
    $.connection.hub.start()
        .done(function(){ console.log('Now connected, connection ID=' + $.connection.hub.id); })
        .fail(function(){ console.log('Could not Connect!'); });
    });
    
    $.extend(contosoChatHubProxy.client, {
        addContosoChatMessageToPage: function(userName, message) {
        console.log(userName + ' ' + message);
        };
    });
    
    var connection = $.hubConnection();
    var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
    contosoChatHubProxy.on('addContosoChatMessageToPage', function(userName, message) {
        console.log(userName + ' ' + message);
    });
    connection.start()
        .done(function(){ console.log('Now connected, connection ID=' + connection.id); })
        .fail(function(){ console.log('Could not connect'); });
    
    服务端
    public class ContosoChatHub : Hub
    {
        public void NewContosoChatMessage(string name, string message)
        {
            Clients.All.addContosoChatMessageToPage(name, message);
        }
    }
    
    
    参数是复杂类型
    客户端
    var contosoChatHubProxy = $.connection.contosoChatHub;
    contosoChatHubProxy.client.addMessageToPage = function (message) {
        console.log(message.UserName + ' ' + message.Message);
    });
    
    var connection = $.hubConnection();
    var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
    chatHubProxy.on('addMessageToPage', function (message) {
        console.log(message.UserName + ' ' + message.Message);
    });
    
    服务端
    public class ContosoChatMessage
    {
        public string UserName { get; set; }
        public string Message { get; set; }
    }
    
    public void SendMessage(string name, string message)
    {
        Clients.All.addContosoChatMessageToPage(new ContosoChatMessage() { UserName = name, Message = message });
    }
    
    
    
    客户端调用服务端的方法
    使用server这个属性,方法名符合驼峰命名法,SignalR会自动匹配。
    
    无返回值的服务端方法
    服务端
    public class ContosoChatHub : Hub
    {
        public void NewContosoChatMessage(ChatMessage message)
        {
            Clients.All.addContosoChatMessageToPage(message);
        }
    }
    
    public class ChatMessage
    {
        public string UserName { get; set; }
        public string Message { get; set; }
    }
    
    客户端
    contosoChatHubProxy.server.newContosoChatMessage({ UserName: userName, Message: message}).done(function () {
            console.log ('Invocation of NewContosoChatMessage succeeded');
        }).fail(function (error) {
            console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
        });
    直接调用
    
    contosoChatHubProxy.invoke('newContosoChatMessage', { UserName: userName, Message: message}).done(function () {
            console.log ('Invocation of NewContosoChatMessage succeeded');
        }).fail(function (error) {
            console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
        });
    
    通过invoke方法调用。
    
    
    可以为服务器的方法打上属性标签,此时将不再遵守驼峰命名法,需完全匹配
    用[HubMethodName("myMethodName")]来完成标记
    
    服务端
    public class ContosoChatHub : Hub
    {
        [HubMethodName("NewContosoChatMessage")]
        public void NewContosoChatMessage(string name, string message)
        {
            Clients.All.addContosoChatMessageToPage(name, message);
        }
    }
    
    客户端
    contosoChatHubProxy.server.NewContosoChatMessage(userName, message).done(function () {
            console.log ('Invocation of NewContosoChatMessage succeeded');
        }).fail(function (error) {
            console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
        });
    
    contosoChatHubProxy.invoke('NewContosoChatMessage', userName, message).done(function () {
            console.log ('Invocation of NewContosoChatMessage succeeded');
        }).fail(function (error) {
            console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
        });
    
    
    有返回值的服务端方法
    
    服务端
    public class StockTickerHub : Hub
    {
        public IEnumerable<Stock> GetAllStocks()
        {
            return _stockTicker.GetAllStocks();
        }
    }
    
    public class Stock
    {
        public string Symbol { get; set; }
        public decimal Price { get; set; }
    }
    
    客户端
    function init() {
        return stockTickerProxy.server.getAllStocks().done(function (stocks) {
            $.each(stocks, function () {
                var stock = this;
                console.log("Symbol=" + stock.Symbol + " Price=" + stock.Price);
            });
        }).fail(function (error) {
            console.log('Error: ' + error);
        });
    }
    
    function init() {
        return stockTickerProxy.invoke('getAllStocks').done(function (stocks) {
            $.each(stocks, function () {
                var stock = this;
                console.log("Symbol=" + stock.Symbol + " Price=" + stock.Price);
            });
        }).fail(function (error) {
            console.log('Error: ' + error);
        });
    }
    通过each方法遍历stocks。
    
    
    
    
    如何处理连接生命周期事件
    SignalR提供一下可以处理的连接生命周期事件。
    starting:在连接发送任何数据之前引发。
    received:在连接上收到任何数据时触发,提供收到的数据。
    connectionSlow:当客户端检测到缓慢或频繁掉线时触发。
    reconnectiong:当底层传输开始重新连接时引发。
    reconnected:当底层运输工具重新连接时触发。
    stateChanged:连接的状态发生变化时触发,提供旧状态和新状态。
    disconnected:连接断开时触发。
    
    处理conectionSlow事件
    $.connection.hub.connectionSlow(function(){
    console.('we are currently experiencing difficulties with the connection.');
    });
    
    var connection = $.hubConnection();
    connection.connectionSlow(function () {
        console.log('We are currently experiencing difficulties with the connection.')
    });
    
    
    
    
    如何处理错误
    SignalR JavaScript客户端提供了一个error可以为其添加处理程序的事件。
    还可以使用fail方法为由服务器方法调用产生的错误添加一个处理程序。
    如果没在服务端显示启用详细的错误消息,则SignalR在错误后返回的异常对象
    包含最少的错误信息。出于安全考虑,不建议在生产中发送详细的错误消息给客户端。
    
    在服务端启用详细信息
    var hubConfiguration=new HubConfiguration();
    hubConfiguration.EnableDetailedErrors=true;
    app.MapSignalR(hubConfiguration);
    
    在客户端处理错误信息
    添加一个错误处理程序
    $.connection.hub.error(function (error) {
        console.log('SignalR error: ' + error)
    });
    
    var connection = $.hubConnection();
    connection.error(function (error) {
        console.log('SignalR error: ' + error)
    });
    
    var connection = $.hubConnection();
    connection.error(function (error) {
        console.log('SignalR error: ' + error)
    });
    
    处理来自方法的调用的错误
    contosoChatHubProxy.newContosoChatMessage(userName, message)
        .fail(function(error) { 
            console.log( 'newContosoChatMessage error: ' + error) 
        });
    
    contosoChatHubProxy.invoke('newContosoChatMessage', userName, message)
        .fail(function(error) { 
            console.log( 'newContosoChatMessage error: ' + error) 
        });
    
    
    
    
    启用客户端日志记录
    在start();方法之前。
    $.connection.hub.logging = true;
    $.connection.hub.start();
    
    var connection = $.hubConnection();
    connection.logging = true;
    connection.start();
    

      

  • 相关阅读:
    iOS 苹果开发证书失效的解决方案(Failed to locate or generate matching signing assets)
    iOS NSArray数组过滤
    App Store2016年最新审核规则
    iOS 根据字符串数目,自定义Label等控件的高度
    iOS 证书Bug The identity used to sign the executable is no longer valid 解决方案
    Entity FrameWork 增删查改的本质
    EF容器---代理类对象
    Entity FrameWork 延迟加载本质(二)
    Entity FrameWork 延迟加载的本质(一)
    Entity FrameWork 增删查改
  • 原文地址:https://www.cnblogs.com/xiaoai123/p/6659962.html
Copyright © 2011-2022 走看看