一、前言

SignalR是微软推出的开源实时通信框架。其内部使用Web Socket, Server Sent Events 和 Long Polling作为底层传输方式,SignalR会根据客户端和服务端的支持情况,采用回落机制来选择一种传输方式,Web Socket是首选的。在web开发中,SignalR可以很好的解决传统ajax轮询的问题,真正做到实时通信。

二、编码

  • 首先创建2个项目,一个控制台项目,一个web项目。控制台项目作为SignalR服务端,web项目作为客户端。

  • 先从服务端开始:

    安装NuGet包

    控制台程序作为宿主实现自托管,需要安装:Microsoft.AspNet.SignalR.SelfHost



    添加跨域支持:Microsoft.Owin.Cors

  • 服务端SignalRServer.Program代码:
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks; namespace SignalRServer
{
class Program
{
static void Main(string[] args)
{
var url = "http://localhost:8019";
using (WebApp.Start(url))
{
Console.WriteLine("SignalR运行:" + url);
Console.WriteLine("输入要发送的消息,用户与消息之间用空格隔开:"); var hub = GlobalHost.ConnectionManager.GetHubContext<CustomHub>(); while (true)
{
var str = Console.ReadLine();
hub.Clients.Client(CustomHub.OnLineUsers[str.Split(' ')[0]]).refreshData(str.Split(' ')[1]);
}
}
}
} public class CustomHub : Hub
{
//在线用户
public static ConcurrentDictionary<string, string> OnLineUsers = new ConcurrentDictionary<string, string>(); public override Task OnConnected()
{
string clientName = Context.QueryString["clientName"].ToString();
OnLineUsers.AddOrUpdate(clientName, Context.ConnectionId, (key, value) =>
{
return Context.ConnectionId;
});
Console.WriteLine($"{clientName}:{Context.ConnectionId}已连接。");
return base.OnConnected();
} public override Task OnDisconnected(bool stopCalled)
{
string clientName = Context.QueryString["clientName"].ToString();
string client;
OnLineUsers.TryRemove(clientName, out client);
Console.WriteLine($"{clientName}:{Context.ConnectionId}已断开。");
return base.OnDisconnected(stopCalled);
} public override Task OnReconnected()
{
string clientName = Context.QueryString["clientName"].ToString();
OnLineUsers.AddOrUpdate(clientName, Context.ConnectionId, (key, value) =>
{
return Context.ConnectionId;
});
Console.WriteLine($"{clientName}:{Context.ConnectionId}已重连。");
return base.OnReconnected();
}
} public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
} }

以上代码大致就是指定一个url启动SignalR服务,CustomHub中维护了一个在线客户端集合,控制台根据输入的信息发送到对应的客户端...

  • 下面是客户端

    同样先安装NuGet包

    安装Microsoft.AspNet.SignalR.JS

  • 创建2个视图User1,User2,用来代表2个不同用户

    User1.cshtml代码,支持断线重连:
@{
ViewBag.Title = "Index";
Layout = null;
} <script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script id="signalr_script" src="http://localhost:8019/signalr/hubs"></script> <script type="text/javascript">
$(function () {
//连接Signalr服务器
signalrInit();
}); //signalr初始化配置
function signalrInit() {
try {
//Set the hubs URL for the connection
$.connection.hub.url = 'http://localhost:8019/signalr';
$.connection.hub.qs = { "clientName": "user1" }; // Declare a proxy to reference the hub.
var chat = $.connection.customHub; // Create a function that the hub can call to broadcast messages.
chat.client.refreshData = function (message) {
//TODO:收到服务端数据
appendMessage(message);
}; signalrConnection(); $.connection.hub.disconnected(function () {
appendMessage('SignalR连接断开!');
//重连
setTimeout(signalrConnection, 10000);
});
//$.connection.hub.stateChanged(function (change) { console.log(change); });
} catch (e) {
appendMessage("SignalR连接异常" + e);
//重新加载hubs
$.getScript('http://localhost:8019/signalr/hubs');
//重新初始化 断线重连
setTimeout(signalrInit, 10000);
}
} //signalr连接
function signalrConnection() {
$.connection.hub.start()
.done(function () { appendMessage('SignalR建立连接成功'); })
.fail(function () { appendMessage('SignalR建立连接失败'); });
} function appendMessage(message) {
$("#box").append("<p>" + message + "</p>");
}
</script> <h1>User1</h1>
<div id="box"> </div>

User2.cshtml代码:

@{
ViewBag.Title = "Index";
Layout = null;
} <script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script id="signalr_script" src="http://localhost:8019/signalr/hubs"></script> <script type="text/javascript">
$(function () {
//连接Signalr服务器
signalrInit();
}); //signalr初始化配置
function signalrInit() {
try {
//Set the hubs URL for the connection
$.connection.hub.url = 'http://localhost:8019/signalr';
$.connection.hub.qs = { "clientName": "user2" }; // Declare a proxy to reference the hub.
var chat = $.connection.customHub; // Create a function that the hub can call to broadcast messages.
chat.client.refreshData = function (message) {
//TODO:收到服务端数据
appendMessage(message);
}; signalrConnection(); $.connection.hub.disconnected(function () {
appendMessage('SignalR连接断开!');
//重连
setTimeout(signalrConnection, 10000);
});
//$.connection.hub.stateChanged(function (change) { console.log(change); });
} catch (e) {
appendMessage("SignalR连接异常" + e);
//重新加载hubs
$.getScript('http://localhost:8019/signalr/hubs');
//重新初始化 断线重连
setTimeout(signalrInit, 10000);
}
} //signalr连接
function signalrConnection() {
$.connection.hub.start()
.done(function () { appendMessage('SignalR建立连接成功'); })
.fail(function () { appendMessage('SignalR建立连接失败'); });
} function appendMessage(message) {
$("#box").append("<p>" + message + "</p>");
}
</script> <h1>User2</h1>
<div id="box"> </div>

三、效果

  • 服务端和客户端的代码已完成,现在先运行一下服务端控制台程序。右键编译好的SignalRServer.exe,以管理员身份运行(最好是管理员身份运行,不然可能会报错)。

  • 运行客户端,浏览器分别打开User1,User2页面





    客户端已经显示连接成功



    服务端也显示2个已连接
  • 向User1发送消息:

  • 向User2发送消息:

四、总结

以上就是SignalR的基本使用。

有一些可能的坑:

1.服务端控制台启动报错:尝试用管理员身份启动

2.服务端启动正常,客户端却无法连接,报错Cannot read property 'client' of undefined:有时候可能是端口的问题,换一个端口试一下

3.程序放到服务器,通过外网IP无法连接:WebApp.Start()尝试使用*号格式:http://*:8019

SignalR控制台自托管服务端向web客户端指定用户推送数据,客户端断线重连的更多相关文章

  1. 使用SignalR ASP.NET Core来简单实现一个后台实时推送数据给Echarts展示图表的功能

    什么是 SignalR ASP.NET Core ASP.NET Core SignalR 是一种开放源代码库,可简化将实时 web 功能添加到应用程序的功能. 实时 web 功能使服务器端代码可以立 ...

  2. SignalR指定用户推送消息

    一.首先,在MVC项目中安装SingalR包(SingalR2.0需要.net4.5以上,VS2010可以安装1.1.3版本,本例为VS2010+SignalR1.1.3). 打开工具-NuGet程序 ...

  3. SuperSocket主动从服务器端推送数据到客户端

    关键字: 主动推送, 推送数据, 客户端推送, 获取Session, 发送数据, 回话快照 通过Session对象发送数据到客户端   前面已经说过,AppSession 代表了一个逻辑的 socke ...

  4. Asp.net Core3.1+Vue 使用SignalR推送数据

    本文就简单使用 往前端页面推送消息 SignalR 是什么 SignalR是一个.NET Core/.NET Framework的开源实时框架. SignalR的可使用Web Socket, Serv ...

  5. 使用Pushlet将消息从服务器端推送到客户端

    使用Pushlet来实现服务器端向客户端推送信息 1.   实现方式: 有两种实现方式: 1.         通过配置文件来实现定时的从服务器端向客户端推送信息 2.         通过API主动 ...

  6. ASP.NET SignalR 系列(四)之指定对象推送

    在上一章讲到了广播推送,即所有订阅的用户都能收到,这种适合于信息广播. 接下来介绍如何给指定的对象推送 在讲这个之前先说明一下连接创建的基础知识 1.每个页面与服务端创建连接并启动时,这时服务端会产生 ...

  7. 利用Ajax+MSMQ(消息队列)+WebService实现服务器端向客户端的信息推送

    需求: 每当数据库有数据更新时,推送到客户端 软需求: 1.服务器资源有限,要求资源占用尽可能小: 2.项目可控,不许调用第三方不可信不稳定的方法. 已有事例: 1.58到家采用的方法是TCP的长连接 ...

  8. C#服务端通过Socket推送数据到Android端App中

    需求: 描述:实时在客户端上获取到哪些款需要补货. 要求: 后台需要使用c#,并且哪些需要补货的逻辑写在公司框架内,客户端采用PDA(即Android客户端 版本4.4) . 用户打开了补货通知页面时 ...

  9. DP使用GUI推送WIN客户端是报110:1022错误的解决办法

    在使用GUI推送WIN客户端时,输入用户名和密码后报错: [Critical 110::1022]  Cannot connect to the SCM (Service Control Manage ...

随机推荐

  1. Java并发编程:线程和锁的使用与解析

    线程的使用  新建线程 新建一个线程有两种方法:继承Thread类,然后重写run方法:实现Runnable接口,然后实现run方法.实际上Thread类也是实现的Runnable接口,再加上类只能单 ...

  2. Asp.net Core 3.1 Razor视图模版动态渲染PDF

    Asp.net Core 3.1 Razor视图模版动态渲染PDF 前言 最近的线上项目受理回执接入了电子签章,老项目一直是html打印,但是接入的电子签章是仅仅对PDF电子签章,目前还没有Html电 ...

  3. clickhouse基本操作一

    常用SQL 创建表 1 2 3 4 5 6 7 CREATE TABLE b6logs( eventDate Date, impid UInt64, uid String, idfa String, ...

  4. UVALive5846

    题目大意:见刘汝佳<算法竞赛入门经典——训练指南>P173. 解题思路: 如果要直接求所有单色三角形的个数似乎不简单,正难则反,先求出所有非单色三角形 cnt,answer = C(n,3 ...

  5. 软链接 vs. 硬链接

    ​链接大家都用过,比如 Windows 中的快捷方式就是一种链接,可是 Linux 里又分硬链接和软链接,它们表示什么意思,又有什么区别呢,本文来给大家做一个解释. Inode 索引节点 要想理解硬链 ...

  6. SPL常用函数

    使用SPL_AUTOLOAD_REGISTER装载类 <?php /** * libs/Test.class.php */ class Test { function __construct() ...

  7. 干货!JNPF快速开发平台功能一览

      JNPF,采用主流的两大技术Java/.Net开发,是一套低代码开发平台,可视化开发环境,有拖拽式的代码生成器,灵活的权限配置.SaaS服务,强大的接口对接,随心可变的工作流引擎,一站式开发多端使 ...

  8. SVM——支持向量机(完整)

    最基本的SVM(Support Vector Machine)旨在使用一个超平面,分离线性可分的二类样本,其中正反两类分别在超平面的一侧.SVM算法则是要找出一个最优的超平面. 线性可分SVM 优化函 ...

  9. GRpc添加客户端的四种方式

    随着微服务的发展,相信越来越多的.net人员也开始接触GRpc这门技术,大家生成GRpc客户端的方式也各不相同,今天给大家介绍一下依据Proto文件生成Rpc客户端的四种方式 前提:需要安装4个Nug ...

  10. 关于mantisBT2.22安装插件Inline column configuration 2.0.0时提示缺少依赖jQuery UI Library 1.8

    1.首先直接下载最新的那个1.12即可 https://github.com/mantisbt-plugins/jQuery-UI/releases 2.上传到mantis的插件目录下:……manti ...