您的位置:首页 > 其它

一步一步学习SignalR进行实时通信_3_通过CORS解决跨域

2015-08-16 22:40 309 查看

一步一步学习SignalR进行实时通信\_3_通过CORS解决跨域
SignalR


一步一步学习SignalR进行实时通信_3_通过CORS解决跨域前言
关于start()的补充
跨域解决方案JSONP
CORSCORS跨域演示

结束语
参考文献

前言

这周工作比较忙,一直没有时间学习SignalR,大致希望一周能写一篇关于SignalR的文章。上一篇用Persistent Connections方式实现了个简单的在线聊天功能,这次我们继续深入学习。

关于start()的补充

在上一篇文章里前台的html页面我们通过几句javascript创建了一个,代码如下,也可以下载上次的源码。

<!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>

[/code]这里需要做些说明:通过代码
var connection = $.connection("/echo");

我们创建了一个连接,通过
connection.start().done()
来开启连接并在连接完成时处理我们需要处理的事件。
如果你将以下代码

connection.start().done(function () {

connection.send('Hi');

});

[/code]分成2部分写,如:

connection.start();

connection.send('Hi');

[/code]那么你必须注意:
虽然你在
connection.send()
之前调用了
connection.start()
开启了连接,但是
connection.start()
是一个异步方法,意味着有可能你在调用
connection.send()
时connection并未开启,那么项目将会报错。
正确方法如之前代码所示,再加上一段开启失败的代码:

var connection = $.connection("/echo");

connection.start(function() {

// 连接开启成功才会进入这里

connection.send("Hi");

}).fail(function() {

//连接开启失败则进入这里

alert("服务开启失败");

});

[/code]

跨域解决方案

上篇文章里有同学问到跨域的问题,那么在接下来的时间我将会带着大家一起学习。
在SignalR解决跨域,有两种方式:第一种是JSONP,第二种是CORS。

JSONP

如果你的服务必须要支持老版本的浏览器,那么JSONP是唯一选择,否则处于安全的考虑这并不被推荐,具体什么安全因素我并不知晓(有同学知道的话可以说明下),基于快速学习的情况下,我们无需纠缠于此。服务器默认会禁用此功能,我们可以通过初始化时提供一个ConnectionConfiguration对象并设置EnableJSONP属性为true来激活此功能。

public class Startup

{

public void Configuration(IAppBuilder app)

{

var config = new ConnectionConfiguration()

{

EnableJSONP = true

};

app.MapSignalR<EchoConnection>("/echo", config);

}

}

[/code]我想这几句代码应该很好理解,我们在前面提到过
MapSignalR<TConnection>()
有许多重载方法,这是另一个重载方法通过提供一个
ConnectionConfiguration
对象进行相关配置。

CORS

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

           }

);

}

}

[/code]代码应该也不难,这次我们通过
app.Map()
进行映射,第一个参数是映射的地址,第二个参数是一个lambda表达式,通过
UseCors(CorsOptions.AllowAll)
允许允许跨域。

CORS跨域演示

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个包都要添加引用




源码下载
本文发布至作业部落

参考文献

SignalR Programming in Microsoft ASP.NET pdf 下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: