原文: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]\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客户端的更多相关文章

  1. Web客户端数据存储学习笔记——Cookie

    今天对登录访问的安全以及web客户端存储做了一些大致的学习,决定在这方面加深理解,记录在博客里.第一个接触到的是Cookie... WHAT? WHY? HOW? 在学习cookie的使用时发现其名称 ...

  2. 浏览器与web客户端的HTTP交互过程

    未经许可谢绝以任何形式对本文内容进行转载! HTTP协议是常见的几种应用层协议之一,当我们用浏览器和web客户端进行交互时html页面等内容的传输都是依靠该协议完成的.值得注意的是,HTTP使用的是T ...

  3. python web编程-web客户端编程

    web应用也遵循客户服务器架构 浏览器就是一个基本的web客户端,她实现两个基本功能,一个是从web服务器下载文件,另一个是渲染文件 同浏览器具有类似功能以实现简单的web客户端的模块式urllib以 ...

  4. redis web 客户端工具 redis-admin

    redis-admin是基于java的redis web客户端(redis client),以方便广大程序员使用redis为宗旨,集五种数据结构增删改查于一身. https://github.com/ ...

  5. 512MB内存VPS服务器安装宝塔WEB客户端建站 - 环境部署篇

    原本以为我们很多网友用VPS搭建网站不会用WEB面板,而采用一键包或者自己部署编译环境,但是最后发现其实目前我们使用WEB面板的还是挺多的,无论是免费还是付费的都有不少人使用.比如当初一直免费的AMH ...

  6. zookeeper的WEB客户端zkui使用

    转载自:http://blog.csdn.net/csolo/article/details/53694665 前面几篇实践说明了zookeeper如何配置和部署,如何开发,因为大多是后台操作,对于维 ...

  7. WEB客户端和服务器

    # encoding=utf-8 #python 2.7.10 #xiaodeng #HTTP权威指南 #HTTP协议:超文本传输协议是在万维网上进行通信时所使用的协议方案. #WEB客户端和服务器: ...

  8. 工具:SVN的Web客户端(ViewVC、SVNWebClient、sventon)和任务管理(Trac、Collaboa)

    http://www.blogjava.net/evanwhj/archive/2006/04/06/39498.aspx 在前面一篇文章中,痛诉了安装ViewVC for Subversion的种种 ...

  9. 命令行web客户端与HTTP REST API调试工具

    1.命令行web客户端 curl wget httpie 2.优雅的REST API调试工具 insomnia postman

  10. [Real World Haskell翻译]第22章 扩展示例:Web客户端编程

    第22章 扩展示例:Web客户端编程 至此,您已经看到了如何与数据库交互,解析一些数据,以及处理错误.现在让我们更进了一步,引入Web客户端库的组合. 在本章,我们将开发一个真正的应用程序:一个播客下 ...

随机推荐

  1. Android学习Scroller(三)——控件平移划过屏幕 (Scroller简单使用)

    MainActivity例如以下: package cc.cn; import android.os.Bundle; import android.view.View; import android. ...

  2. 双机热备的Quartz集群

    sqlserver搭建高可用双机热备的Quartz集群部署[附源码]   一般拿Timer和Quartz相比较的,简直就是对Quartz的侮辱,两者的功能根本就不在一个层级上,如本篇介绍的Quartz ...

  3. NOIP模拟 - 莫队

    题目描述 给定一个元素个数为 n 的整数数组 a 和 Q 个问题,每个问题有 x,y 两个参数,请统计共有多少个整数 K 满足 K 在 a[x]-a[y] 中出现了恰好 K 次. 输入格式 第一行两个 ...

  4. WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush)

    原文:WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush) 前面我们介绍到,Path对象表示一个用直线或者曲线连接的图形,我们可以使用Path.Data ...

  5. Shell脚本实现在Linux系统中自动安装JDK

    A:本脚本运行的机器,Linux B:待安装JDK的机器, Linux 首先在脚本运行的机器A上确定可以ssh无密码登录到待安装jdk的机器B上,然后就可以在A上运行本脚本: 复制代码 代码如下: $ ...

  6. MIPS重返硅谷 放眼AI未来

    MIPS最近以一家独立公司之姿重新回到了矽谷,在Tallwood的带领下积极投入原有的嵌入式业务,并放眼下一代人工智能(AI)领域.   MIPS最近以一家独立公司之姿重新回到了矽谷——加州圣塔克拉拉 ...

  7. 执行hdfs namenode -importCheckpoint时出现No image directories available!

    在https://issues.apache.org/jira/browse/HDFS-4705找到了答案需要在hdfs-site.xml中配置 <!--指定fsimage存储目录--> ...

  8. 利用WPF建立自己的3d gis软件(非axhost方式)(五)在鼠标点击的位置增加UI

    原文:利用WPF建立自己的3d gis软件(非axhost方式)(五)在鼠标点击的位置增加UI 先下载SDK:https://pan.baidu.com/s/1M9kBS6ouUwLfrt0zV0bP ...

  9. Java_压缩与解压工具类

    转载请注明出处:http://blog.csdn.net/y22222ly/article/details/52201675 zip压缩,解压 zip压缩与解压主要依靠java api的两个类: Zi ...

  10. OpenCV绘制朱利亚(Julia)集合图形

    朱利亚集合是一个在复平面上形成分形的点的集合.以法国数学家加斯顿·朱利亚(Gaston Julia)的名字命名. 朱利亚集合可以由下式进行反复迭代得到: 对于固定的复数c,取某一z值(如z = z0) ...