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

  1. 使用Visual Studio 2019 创建一个MVC工程-SignalRMvcChat

创建ASP.NET Web应用程序

配置项目
  1. 选择MVC,然后身份验证上,选择“无身份验证”,然后单击“创建”。

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

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

  1. 用以下代码替换新建的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);
}
}
}
  1. 在项目上,右键选择 添加>,命名为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中添加节点: ,来指定启动类;

  1. 在Home控制器中添加一个方法,来返回下面聊天步骤所使用的页面:在 HomeController.cs 中添加以下方法:
public ActionResult Chat()
{
return View();
}
  1. 在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


1

可能出现的问题:

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的应用的更多相关文章

  1. asp.net MVC SignalR 与数据库 实时同步显示

    asp.net MVC SignalR 与数据库 实时同步显示 错误:未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持.如果希望使用通知,请为此数据库启用 ...

  2. ASP.NET MVC SignalR(1):背景

    系列目录:ASP.NET MVC SignalR 关键词:HTTP.轮询.WebSocket.Server-Sent Events.长轮询.forever frame. 1. HTTP HTTP(Hy ...

  3. AngularJS+ASP.NET MVC+SignalR实现消息推送

    原文:AngularJS+ASP.NET MVC+SignalR实现消息推送 背景 OA管理系统中,员工提交申请单,消息实时通知到相关人员及时进行审批,审批之后将结果推送给用户. 技术选择 最开始发现 ...

  4. ASP.NET MVC SignalR

    本系列博文主要介绍了 ASP.NET SignalR 的相关知识与开发,参考来源为<ASP.NET SignalR 编程实践>. 目录: SignalR背景 SignalR概述

  5. Asp.net MVC + Signalr 实现多人聊天室

    Asp.net SignalR 简介: 首先简单介绍一下Signalr ,我也是刚接触,觉得挺好玩的,然后写了一个多人聊天室. Asp.net SignalR 是为Asp.net 开发人员提供的一个库 ...

  6. SignalR + KnockoutJS + ASP.NET MVC 实现井字游戏

    SignalR + KnockoutJS + ASP.NET MVC 实现井字游戏   1.1.1 摘要 今天,我们将使用SignalR + KnockoutJS + ASP.NET MVC实现一个实 ...

  7. ASP.NET MVC和EF集成AngularJS开发

    参考资料: 如何在ASP.NET MVC和EF中使用AngularJS AngularJS+ASP.NET MVC+SignalR实现消息推送 [AngularJs + ASP.NET MVC]使用A ...

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

    简单介绍 关于SignalR的简单实用 请参考 Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室) 在上一篇中,我们只是介绍了简单的消息推送,今天我们来修改一下,实现 ...

  9. Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)

    简介       ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端 ...

随机推荐

  1. c++ 对象池的创建

    template <class T> class ObjectPool { public: using DeleterType = std::function<void(T*)> ...

  2. oracle函数 LTRIM(c1,[,c2])

    [功能]删除左边出现的字符串 [参数]C1 字符串 c2 追加字符串,默认为空格 [返回]字符型 [示例] SQL> select LTRIM('   gao qian jing',' ') t ...

  3. @topcoder - SRM611D1L3@ ElephantDrinking

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定有一个 n*n 的平原,其中一些格子有些泉水.泉水每单位时间 ...

  4. HZOJ visit

    对于前30%的数据,可以考虑dp,f[i][j][k]表示时间为i,在i,j位置的方案数,枚举转移即可.要注意的是可以走到矩阵外. 对于另外30%数据,考虑推一下式子,设向右走y步,左z,上s,下x. ...

  5. oralce 减少访问数据库的次数

    当执行每条SQL语句时, ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等. 由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作 ...

  6. lrj 9.4.1 最长上升子序列 LIS

    p275 d(i)是以Ai为结尾的最长上升子序列的长度 <算法竞赛入门经典-训练指南>p62 问题6 提供了一种优化到 O(nlogn)的方法. 文本中用g(i)表示d值为i的最小状态编号 ...

  7. Laravel 服务提供者实例教程 —— 创建 Service Provider 测试实例

    从某种意义上说,服务提供者有点类似HTTP控制器,HTTP控制器用于为相关路由注册提供统一管理,而服务提供者用于为相关服务容器提供统一绑定场所,此外服务提供者还可以做一些初始化启动操作.Laravel ...

  8. Python--day48--今日内容

  9. 困扰的问题终于解决了-docker时区不正确的问题修改记

    前一阵子有一台服务器,mysql的时间比北京时间晚了8个小时.我知道是时区的问题,但是不知道为什么弄成这样,宿主机没有问题,后来一看mysql的docker,时区是错的. mybatis-plus打印 ...

  10. 清除SVN未版控文件

    用Git时,git clean -df 可以清除所有没有add的文件,得到一个干净的工作空间. 用SVN没有这样的命令,当然可以 svn export 得到一个干净的工作空间,但会花很长时间,而且没有 ...