ASP.Net MVC SignalR的应用
ASP.Net MVC SignalR的应用
最近做的一个MVC项目有个模块是要使用即时通信实现弹幕效果。既要考虑通信的实时性也要考虑服务器性能和资源消耗,所幸项目对浏览器的版本没有要求。所以我最先想到用WebSocket来实现,在查询资料时, 看到 SignalR 这个技术,也就是本专题所讨论的对象。在拜读了 史上最全面的SignalR系列教程-认识SignalR ,算是对 SignalR有一个简单的认识,SignalR 是 .NET平台为我们提供的一种简洁高效智能的实时信息交互技术,SignalR 比 WebSocket 还要简单,这简直是我的福音。所以我直接一个Demo开始尝试。
SignalR
关于SignalR的介绍这边就不多赘述,可以去看我上面说的这篇博文史上最全面的SignalR系列教程-认识SignalR 或者直接看Microsoft文档 Introduction to SignalR,SignalR可用于任何即时性的功能;
Demo :使用SignalR和MVC 5实现实时聊天
通过第一部分的介绍,相信大家对SignalR有初步的认识,接下来直接上手一个Demo来看看(我的开发环境:VS2019 + .net 4.6.2 + MVC 5)。步骤参考微软教程 Tutorial: Real-time chat with SignalR 2 and MVC 5。
- 使用Visual Studio 2019 创建一个MVC工程-SignalRMvcChat


- 选择MVC,然后身份验证上,选择“无身份验证”,然后单击“创建”。

- 在项目上右击-添加新建项,选择 Installed > Visual C# > Web > SignalR and then 选择 SignalR Hub Class (v2).

- 将类命名为ChatHub并将其添加到项目中。 此步骤将创建ChatHub.cs集线器类文件,并将一组支持SignalR的脚本文件和程序集引用添加到项目:

- 用以下代码替换新建的ChatHub.cs类文件中的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalRMvcChat
{
public class ChatHub : Hub
{
public void Send(string name, string message)
{
Clients.All.addNewMessageToPage(name, message);
}
}
}
- 在项目上,右键选择 添加>类,命名为Startup.cs,并用以下代码替换新建的Startup.cs类文件中的代码:
using Owin;
using Microsoft.Owin;
[assembly: OwinStartup(typeof(SignalRMvcChat.Startup))]
namespace SignalRMvcChat
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
}
注意: SignalR 框架使用Owin组件,每一个使用的OWin组件的Web框架都需要一个Startup入口类,用来声明OWin组件:
1.项目会自动扫描程序集根下的名为Startup的类,来作为入口类;
2.通过添加 [assembly: OwinStartup(typeof(SignalRChat.Startup))] 标签标记入口类;
3.如果你的启动类不在当前命名空间下,需要在Web.config中添加节点: ,来指定启动类;
- 在Home控制器中添加一个方法,来返回下面聊天步骤所使用的页面:在 HomeController.cs 中添加以下方法:
public ActionResult Chat()
{
return View();
}
- 在Views/Home中添加Chat视图,并用以下代码替换到新建的视图文件中:(注意:视图中所引用的signalR脚本可能跟你实际安装的版本不一样,这里需要你根据实际安装的版本进行修改)
@{
ViewBag.Title = "Chat";
}
<h2>Chat</h2>
<div class="container">
<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" />
<input type="hidden" id="displayname" />
<ul id="discussion"></ul>
</div>
@section scripts {
<!--jQuery库是必需的,默认情况下在_Layout.cshtml引用. -->
<!--引用SignalR库. -->
<script src="~/Scripts/jquery.signalR-2.2.2.min.js"></script>
<!--引用自动生成的SignalR 集线器(Hub)脚本.在运行的时候在浏览器的Source下可看到. -->
<script src="~/signalr/hubs"></script>
<script>
$(function () {
// 引用自动生成的集线器代理 必须用小写字母开头.
var chat = $.connection.chatHub;
// 定义服务器端调用的客户端addNewMessageToPage来处理接收到的消息.
chat.client.addNewMessageToPage = function (name, message) {
// 将消息添加到ul上.
$('#discussion').append('<li><strong>' + htmlEncode(name)
+ '</strong>: ' + htmlEncode(message) + '</li>');
};
// 获取用户名.
$('#displayname').val(prompt('Enter your name:', ''));
// 设置焦点到输入框.
$('#message').focus();
// 开始连接服务器 done函数表明建立连接成功后为发送按钮注册了一个click事件.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// 调用服务器端集线器的Send方法 也要小写开头.
chat.server.send($('#displayname').val(), $('#message').val());
// 清空输入框信息并获取焦点.
$('#message').val('').focus();
});
});
});
// 这个可选功能将html-encodes消息显示在页面上.
function htmlEncode(value) {
var encodedValue = $('<div />').text(value).html();
return encodedValue;
}
</script>
}
运行一下看看效果:
- 在工具栏中,启用“脚本调试”,然后点击“运行”按钮以在浏览器上调试(注意启动项目要设成当前的这个MVC项目)。

-进入聊天页面 ~/Home/Chat

可能出现的问题:
The following errors occurred while attempting to load the app.

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 ,然后跟着提示在web.config的appSetting中添加如下的节点:
<appSettings>
<add key="owin:AutomaticAppStartup" value="false" />
...
</appSettings>
运行居然真的就不报错,但是问题更大条了。在聊天页面并没有生成SignalR代理的hubs的脚本文件,出现了Uncaught TypeError: Cannot read property 'client' of undefined错误
。


对比了微软官方使用 SignalR 步骤,才认识到 SignalR 框架使用Owin组件,一定要指定一个Startup入口类,我是少了以上步骤6,在添加了Startup.cs类之后,问题解决了(添加的Startup.cs类的命名空间为应用程序根目录的名称,去掉之前web.config中加入的错误代码)。对于SignalR代理对象异常,大家还可以看下这篇文章, SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论,只要注意自动生成的集线器脚本中的代理名称和服务端方法都是小写字母开头,调用的时候使用小写就可以避免这个问题。
以上就是今天给大家的分享全部内容了,祝大家元旦快乐!
参考文章
ASP.Net MVC SignalR的应用的更多相关文章
- asp.net MVC SignalR 与数据库 实时同步显示
asp.net MVC SignalR 与数据库 实时同步显示 错误:未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持.如果希望使用通知,请为此数据库启用 ...
- ASP.NET MVC SignalR(1):背景
系列目录:ASP.NET MVC SignalR 关键词:HTTP.轮询.WebSocket.Server-Sent Events.长轮询.forever frame. 1. HTTP HTTP(Hy ...
- AngularJS+ASP.NET MVC+SignalR实现消息推送
原文:AngularJS+ASP.NET MVC+SignalR实现消息推送 背景 OA管理系统中,员工提交申请单,消息实时通知到相关人员及时进行审批,审批之后将结果推送给用户. 技术选择 最开始发现 ...
- ASP.NET MVC SignalR
本系列博文主要介绍了 ASP.NET SignalR 的相关知识与开发,参考来源为<ASP.NET SignalR 编程实践>. 目录: SignalR背景 SignalR概述
- Asp.net MVC + Signalr 实现多人聊天室
Asp.net SignalR 简介: 首先简单介绍一下Signalr ,我也是刚接触,觉得挺好玩的,然后写了一个多人聊天室. Asp.net SignalR 是为Asp.net 开发人员提供的一个库 ...
- SignalR + KnockoutJS + ASP.NET MVC 实现井字游戏
SignalR + KnockoutJS + ASP.NET MVC 实现井字游戏 1.1.1 摘要 今天,我们将使用SignalR + KnockoutJS + ASP.NET MVC实现一个实 ...
- ASP.NET MVC和EF集成AngularJS开发
参考资料: 如何在ASP.NET MVC和EF中使用AngularJS AngularJS+ASP.NET MVC+SignalR实现消息推送 [AngularJs + ASP.NET MVC]使用A ...
- Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)
简单介绍 关于SignalR的简单实用 请参考 Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室) 在上一篇中,我们只是介绍了简单的消息推送,今天我们来修改一下,实现 ...
- Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)
简介 ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端 ...
随机推荐
- datetimepicker —— 日期选择控件
一.依赖 <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel=&qu ...
- oracle函数 ROWIDTOCHAR(rowid)
[功能]转换rowid值为varchar2类型 [参数]rowid,固定参数 [返回]返回长度为18的字符串 [示例] SELECT ROWIDTOCHAR(rowid) FROM DUAL; [说明 ...
- Python基础:22__slots__类属性
1:工厂函数 由于类型和类的统一,因而可以子类化Python数据类型.但是所有的Python 内建的转换函数现在都是工厂函数.当这些函数被调用时,你实际上是对相应的类型进行实例化.比如下面的函数都已经 ...
- 在线url网址编码、解码
>>在线url网址编码.解码<<
- CSS检测窗口大小显示和隐藏内容
代码不多 用css写的话简单一点 @media (max-width: 1024px) { #hidden { display: none; } } max-width 是要检测的宽度
- css3 word-wrap属性
允许长单词换行到下一行: word-wrap:break-word
- springboot2.04与activiti 6.0集成
本文就不对activiti做解释,下面直接看项目集成 以下顺序方面根据我的理解来,可以先从第二章看,再看第一张与第三章 增加activiti表的API,备注用. 目录 一.springboot2.X集 ...
- 【CSS3】loading动画
HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- linux用户权限管理, chmod, ln
1 /etc/passwd文件 用户名 密码 UID GID Full Name 主目录 ...
- react入门:todo应用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...