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();
    

      

  • 相关阅读:
    假期编程
    VC++ MFC Progress Control 进度条
    MFC禁止窗口最大化按钮和禁止改变窗口大小
    VC++ MFC CheckBox
    VC++ 复制整个文件夹
    VS2010 MFC 动态编译以静态编译发布
    VC++ 注册表
    VC++ 删除文件夹
    VC++ MFC 文件处理ANSI
    VC++ MFC Form界面创建和修改总结
  • 原文地址:https://www.cnblogs.com/xiaoai123/p/6659962.html
Copyright © 2011-2022 走看看