有关于MVC SignalR的问题

Posted 程序园丁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有关于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" />

 

如果有什么错误的地方,请园友指出,以防误导新人,谢谢!

以上是关于有关于MVC SignalR的问题的主要内容,如果未能解决你的问题,请参考以下文章

Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)

SignalR 2.0 CORS Chrome 禁用 Web 安全奇怪行为

MVC5使用SignalR进行双向通信

SignalR - 从服务器端代码调用 Hub 类方法(存在于单独的 MVC 项目中)

SignalR系列教程:在MVC在使用SignalR

SignalR 具有 MVC IIS 客户端模拟当前 Windows 用户