SignalR--Web客户端
Posted 小艾123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SignalR--Web客户端相关的知识,希望对你有一定的参考价值。
这里说web客户端其实是javascript起的作用,也可以说是JavaScript客户端。
官方的标题的JavaScript客户端。
下面的翻译,同样的代码的形式上传。篇幅过长,交流[email protected]。
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]\packages\Microsoft.AspNet.SignalR.Utils.2.1.0\tools 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();
以上是关于SignalR--Web客户端的主要内容,如果未能解决你的问题,请参考以下文章