Monthly Archives: 二月 2014

SignalR的使用

前言

随着Ajax越来越普遍的使用,前端页面跟后台服务也越来越密切的进行交互,实现前后端进行实时的消息传递尤为重要,一文件上传为例,现在普遍使用ajax上传然后通过flash进行文件进度的显示,这是目前普遍的用法。
而在.net 4.0以后,出现了一种新的实现页面跟后端服务实时消息传递的方式:SignalR

SignalR简介

官方解释:
当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据。
实现实时服务器与客户端通信。
是一个开源.NET 库生成需要实时用户交互或实时数据更新的 web 应用程序。

SignalR的出现,让页面通过javascript可以很简单的调用后端服务的方法,而在后端也可以很简单的直接调用javascript所实现的方法,从而达到前后端可以进行实时通信。
注意:
SignalR 会自动管理连接。客户端和服务器之间的连接是持久性的,不像传统的 HTTP 连接。

SignalR传输方式
SignalR会根据当前浏览器自动选择适当的传输方式。在最坏的情况下,SignalR会选择使用长轮询(Long Polling).
SignalR会依照下列顺序来判定使用那种传输方式:

  • 1.如果浏览器是 Internet Explorer8 或更早版本,则使用长轮询。
  • 2.如果配置了 JSONP(即连接启动时 jsonp 参数设置为 true),则使用长轮询。
  • 3.如果要建立跨域连接(即 SignalR 终结点和宿主页不在相同的域中),并且满足以下条件,则会使用 WebSocket:
    • 3.1客户端支持 CORS(跨域资源共享)
    • 3.2客户端支持 WebSocket
    • 3.3服务器支持 WebSocket
    • 如果这些条件中的任何一条不满足,将使用长轮询.
  • 4.如果未配置 JSONP 并且连接没有跨域,只要客户端和服务器都支持的话,将使用 WebSocket。
  • 5.如果客户端或服务器不支持 WebSocket,则尽量使用服务器发送事件。Forever Frame。
  • 7.如果 Forever Frame 失败,则使用长轮询。

长轮询(long polling)与传统Ajax的不同之处

  • 服务器端会阻塞请求直到有数据传递或超时才返回。
  • 客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
  • 当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。

SignalR使用

1.官方实例
参考:
根据官网步骤很容易成功创建SignalR的demo.

需要注意的是,本人为了在.net 4.0下演示,所以实用的SignalR 1.x版本。

2.模拟实例
编程是需要自己动手实践的。下面我将根据在上面创建的项目中模拟一个实时进度条的demo.
说明:
页面上就只有一个按妞,点击按钮后,会发送ajax请求道后端,后端会不停发送消息给页面,页面根据接收到的消息来控制进度条。
HTML 代码(Interaction.aspx)

页面后台代码(Interaction.aspx.cs)

Hub类(InteractionHub.cx)

说明:
1.Hub类,在javascript中使用是采用驼峰命名法。所以注意大小写的使用.
2.javascript注意实现hub类中需要被前端调用的方法
3.javascript中,注意使用client 和server 关键字来调用前端方法和后端方法。
4.当web应用中使用了较多的SignalR连接来通信时, 注意使用连接组(Group)来将匹配的signalR连接对应起来。请参考上例 InteractionHub类.

demo代码下载:SignalRDemo(请使用VS2012打开)

参考资料:
SignalR 简介必读

MVC中的文件上传-小结

web开发中,文件的上传是非常基本功能之一。
在asp.net中,通常做法是利用webservice 来接收文件请求,这样做的好处就是全站有了一个统一的文件上传接口,并且根据网站的实际情况,可以将webservice部署到其他服务器上,可以兼容考虑将来的分布存储等等问题。

在MVC中实现文件上传主要有2中方式:
1.普通Controller实现文件上传
2.ApiController实现文件上传

普通Controller实现文件上传
在普通的Controller中实现文件上传时,需要使用到HttpPostedFileBase类 来接收文件。调用HttpPostedFileBase 实例对象的SaveAs()方法,就可以将文件保存在服务器中,示例代码如下:
HTML片段:

Controller中的Action片段:

需要注意2个问题:
1. 注意给form表单加上enctype = “multipart/form-data” 属性,否则会导致Action的参数HttpPostedFileBase 对象接收不到文件。
2. 注意文件大小,IIS中默认上传的文件大小为4MB ,超过这大小的文件需要在修改配置文件。

上传大文件时修改文件大小限制如下:
第一步:asp.net中的文件大小限制

第二步:IIS中文件大小限制

ApiController实现文件上传

通过ApiController来实现文件上传时,不得不参考一下官方文档了,建议先去阅读一下。

我自己在实现Demo时, 开发环境为.net 4.0。
HTML片段:

ApiController代码:

如上代码,区别与官网给出的.net 4.0 版本的代码的。

请注意ReNameMultipartFormDataStreamProvider 为自定义类,继承自MultipartFormDataStreamProvider, 这个累的目的就是对上传上来的文件在保存到服务器时,保留文件的扩展名。MultipartFormDataStreamProvider类默认保存的文件是没有扩展名称的。当然我自己这里实现的方式的确挺土的,演示Demo明白思议即可,呵呵。

到这里就差不多了,后面准备实现Ajax+SingR来实现文件上传时显示上传进度的Demo。

参考资料:
Confusing required maxRequestLength and maxAllowedContentLength settings

http://forums.iis.net/t/1169846.aspx

关于MVC4.0 WebAPI上传图片重命名以及图文结合

http://www.cnblogs.com/ang/archive/2012/10/24/2634176.html

ASP.NET Web Api Self Host大文件上传功能

http://www.cnblogs.com/fenglin1985/archive/2013/01/29/2879926.html