SignalR
html
这周工做比较忙,一直没有时间学习SignalR,大体但愿一周能写一篇关于SignalR的文章。上一篇用Persistent Connections方式实现了个简单的在线聊天功能,此次咱们继续深刻学习。java
在上一篇文章里前台的html页面咱们经过几句javascript建立了一个,代码以下,也能够下载上次的源码。jquery
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>persistent connections</title> <script src="Scripts/jquery-1.10.2.min.js"></script> <script src="Scripts/jquery.signalR-2.0.0.min.js"></script></head><body> <h1>Echo service</h1> <div> <input type="text" id="text" /> <button id="send">Send</button> </div> <script> $(function () { var connection = $.connection("/echo"); connection.logging = true; connection.received(function (data) { $("body").append(data + "<br />"); }); connection.error(function (err) { alert("存在一个错误. \n" + "Error: " + err.message); }); connection.start().done(function () { $("#send").click(function () { connection.send($("#text").val()); $("#text").val("").focus(); }); }); }); </script></body></html>
这里须要作些说明:经过代码var connection = $.connection("/echo");
咱们建立了一个链接,经过connection.start().done()
来开启链接并在链接完成时处理咱们须要处理的事件。
若是你将如下代码json
connection.start().done(function () { connection.send('Hi');});
分红2部分写,如:跨域
connection.start();connection.send('Hi');
那么你必须注意:
虽然你在connection.send()
以前调用了connection.start()
开启了链接,可是connection.start()
是一个异步方法,意味着有可能你在调用connection.send()
时connection并未开启,那么项目将会报错。
正确方法如以前代码所示,再加上一段开启失败的代码:浏览器
var connection = $.connection("/echo");connection.start(function() { // 链接开启成功才会进入这里 connection.send("Hi");}).fail(function() { //链接开启失败则进入这里 alert("服务开启失败");});
上篇文章里有同窗问到跨域的问题,那么在接下来的时间我将会带着你们一块儿学习。
在SignalR解决跨域,有两种方式:第一种是JSONP,第二种是CORS。安全
若是你的服务必需要支持老版本的浏览器,那么JSONP是惟一选择,不然处于安全的考虑这并不被推荐,具体什么安全因素我并不知晓(有同窗知道的话能够说明下),基于快速学习的状况下,咱们无需纠缠于此。服务器默认会禁用此功能,咱们能够经过初始化时提供一个ConnectionConfiguration对象并设置EnableJSONP属性为true来激活此功能。服务器
public class Startup{ public void Configuration(IAppBuilder app) { var config = new ConnectionConfiguration() { EnableJSONP = true }; app.MapSignalR<EchoConnection>("/echo", config); }}
我想这几句代码应该很好理解,咱们在前面提到过MapSignalR<TConnection>()
有许多重载方法,这是另外一个重载方法经过提供一个ConnectionConfiguration
对象进行相关配置。app
CORS是一个独立的框架,它能够很方便的解决跨域问题,经过Nuget安装
安装命令:Install-Package microsoft.owin.cors
CORS是经过Owin实现的,因此咱们须要在项目启动时对他进行一些配置,和作SignalR映射同样实在Startup中进行配置。
public class Startup{ public void Configuration(IAppBuilder app) { //app.MapSignalR<EchoConnection>("/echo"); app.Map("/echo", map => { map.UseCors(CorsOptions.AllowAll); map.RunSignalR<EchoConnection>(); } ); }}
代码应该也不难,此次咱们经过app.Map()
进行映射,第一个参数是映射的地址,第二个参数是一个lambda表达式,经过UseCors(CorsOptions.AllowAll)
容许容许跨域。
JSONP我不作演示了有兴趣的能够本身尝试下,接下来我这里作一个经过CORS来进行跨域聊天。首先我讲上次的项目复制一份,免得再从新打代码,并将复制出来的项目名称由SignalR_1改成SignalR_2_CORS。
项目目录以下图所示:
免得麻烦,我把SignalR_1部署在IIS上面,这就充当了 一个远程的SignalR服务。
部署成功后,如图所示:
此时咱们讲SignalR_2_CORS项目稍做修改
1. 将Startup中的映射删去,此时SignalR_2_CORS已不作SignalR服务器了,只作客户端来链接SignalR_1提供的服务
2. 将echo中的var connection = $.connection("/echo");
改成
var connection = $.connection("http://127.0.0.1:8083/echo");
而后运行SignalR_2_CORS中的echo页面,结果如图所示:
出现了一个错误,这个错误提示是咱们本身写的
由于咱们的SignalR_1并无容许跨域链接,那么在SignalR_2_CORS中固然没法链接,接下来咱们在项目一中容许跨域链接。
从新编译项目一后再刷新下SignalR_1的echo.html页面,注意咱们这个页面地址
而后刷新下SignalR_2_CORS的页面,注意这个地址
链接成功,没有报错了,发送个消息试试看(●ˇ∀ˇ●)
这里经过CORS实现了SignalR的跨域问题,跨域如此简单赶快试试吧 。
注意:在经过Nuget安装CORS包时,我这边提示了Unable to find package 'Microsoft.AspNet.Cors'我已经FQ了,因此这个应该不是须要FQ才能下载,可是在Nuget页面中搜索确实有这个包,具体什么缘由引发的我也不清楚,若是你有碰到这个问题请下载解压并添加引用便可,因为
Microsoft.AspNet.Cors
依赖于Microsoft.AspNet.Cors
,因此里面的2个包都要添加引用