有关于MVC SignalR的问题
刚拜读 @Learning hard 的 [Asp.net 开发系列之SignalR篇]专题一:Asp.net SignalR快速入门
跟着博文一步步操作,这是新人的学习方式
然而笔者的开发环境和 @Learning hard 的有所不同,导致出现了一些小的问题!
首先,新建了一个MVC环境
笔者环境 VS2013 + .net 4.5 + MVC 4.0
新建项目选择的是 Internet 应用程序,为了支持 SignalR,使用 NuGet 控制台往项目中安装了 SignalR (这些都是系统默认,并没有更改所谓的身份验证,其实我也并不知道@Learning hard 及网络上所说的身份认证是什么)
Install-Package Microsoft.AspNet.SignalR
然后,就是需要添加的主体
新建继承 Hub 类的 【SignalR集线器(v2)】类文件,创建一个业务逻辑需要的方法,本例中主要应用到的方法:
// 调用所有客户端的sendMessage方法 Clients.All.sendMessage(name, message);
最后,页面中实例化 SignalR 类,做具体业务逻辑
代码可以参考原文中给出的部分 【原文】
@section scripts { <!--引用SignalR库. --> <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script> <!--引用自动生成的SignalR 集线器(Hub)脚本.在运行的时候在浏览器的Source下可看到 --> <script src="~/signalr/hubs"></script> <script> $(function () { // 引用自动生成的集线器代理 var chat = $.connection.serverHub; // 定义服务器端调用的客户端sendMessage来显示新消息 chat.client.sendMessage = function (name, message) { // 向页面添加消息 $('#discussion').append('<li><strong>' + htmlEncode(name) + '</strong>: ' + htmlEncode(message) + '</li>'); }; // 设置焦点到输入框 $('#message').focus(); // 开始连接服务器 $.connection.hub.start().done(function () { $('#sendmessage').click(function () { // 调用服务器端集线器的Send方法 chat.server.send($('#message').val()); // 清空输入框信息并获取焦点 $('#message').val('').focus(); }); }); }); // 为显示的消息进行Html编码 function htmlEncode(value) { var encodedValue = $('<div />').text(value).html(); return encodedValue; } </script> }
其他
控制器和视图的添加部分就不说了,看看 MVC 入门基本上就会了。
问题来了!
The following errors occurred while attempting to load the app. - No assembly found containing an OwinStartupAttribute. - No assembly found containing a Startup or [AssemblyName].Startup class. To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of "false" in your web.config. To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.
运行之后,应该不少朋友有这样的报错(可能是中文的错误提示)!
看着错误提示,其实直接就知道大概什么情况了,OwinStartupAttribute 没有找到!
紧跟着提示了两种做法,也就是这两种做法误导了初学者!
我们按照提示,于是在网上搜索得到的做法是:
<appSettings> <add key="owin:AutomaticAppStartup" value="false" /> </appSettings>
嘿嘿,你还真别看,居然就真的不报错了,但是下面的问题更大了,因为世界的业务逻辑不行啊,怎么回事,调试发现,浏览到业务所在页面,报错:
GET http://localhost:10292/signalr/hubs 404 (Not Found)
Uncaught TypeError: Cannot read property 'client' of undefined
嘿嘿,这个又是什么……到网上搜了很多,最后搜到: https://github.com/SignalR/SignalR/issues/2649
最后的 @Xiaohongt 回复中给出了正确方法,同时也是官方使用 SignalR 步骤:
http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr
其中有一步骤:
6. In Solution Explorer, right-click the project, then click Add | OWIN Startup Class. Name the new class Startup and click OK.
Note: If you are using Visual Studio 2012, the OWIN Startup Class template will not be available. You can add a plain Class called Startup instead.
然后给出了代码(注意红色):
using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(SignalRChat.Startup))] namespace SignalRChat { public class Startup { public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here app.MapSignalR(); } } }
果然,当添加完这样的类之后,问题解决了,业务功能实现了(去掉之前web.config中加入的错误代码)!
结束言
是的是的,问题解决了,然而……什么情况的,于是乎,就有了下面的结束语:
Owin:Open Web Interface for .NET
支持 Owin 的Web框架有:
更多参见: http://kb.cnblogs.com/page/509236/
每一个使用的OWin组件的Web框架都需要一个StartUp入口类,用来声明OWin组件:
1.项目会自动扫描程序集根下的名为StartUp的类作为入口类
2.通过添加 [assembly: OwinStartup(typeof(SignalRChat.Startup))] 标签标记入口类
3.如果你的启动类不在当前命名空间下 <add key="owin:AppStartup" value="[NameSpace].Startup" />
4.由于第一点的存在,所以如果有名为StartUp的类,并且不是入口点,需要使用 <add key="owin:AutomaticAppStartup" value="false" />
如果有什么错误的地方,请园友指出,以防误导新人,谢谢!