前言

最近在项目中用到了 SSE (Server-Sent Events),用于服务的单向长连接数据推送。因为都是使用 C# 实现的,所以服务端使用的是 HttpListener ,而客户端更简单,只使用了 HttpClient ,连接了之后就一直读流,一旦流读取错误或超时,则尝试重连接。

有感于这种方式简单便捷,便一直一条路走到黑(中间踩了坑),对它进行不断打磨。最后,设计出了一款主打轻量级、兼顾性能、易扩展、开箱即用的纯 C# 实现的 SSE 工具包—— TinyHttpSSE.DotNet ,并已经开源。

简介

TinyHttpSSE.DotNet 在 github 有着详细的介绍,在此仅介绍 SSE。

Server-Sent Events(SSE)是一种基于 HTTP 协议的服务器推送技术,它允许服务器以流的方式向客户端实时推送数据。意味着支持SSE 的浏览器有着对应的支持——EventSource,所以实现 SSE 的 服务端都能与浏览器无缝衔接。

以下,我将基于 TinyHttpSSE.DotNet 和 asp.net core razor 实现一个比分直播的 Demo。

比赛得分Live Demo

  1. 创建项目 asp.net core razor ,添加 nuget 包—— TinyHttpSSE.DotNet.Server

  1. 修改 Program.cs ,设置 HttpSseServer 单例依赖注入,并添加 SseServerHostdService

Program.cs:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddSingleton((service) => {
var config=service.GetService<IConfiguration>();
//SseServerUrl:http://+:9111/msg/
return new HttpSseServer(config.GetValue<string>("SseServerUrl"));
});
builder.Services.AddHostedService<SseServerHostdService>(); builder.Services.AddRazorPages(); var app = builder.Build();

SseServerHostdService.cs:

public class SseServerHostdService : IHostedService
{
private readonly HttpSseServer _server;
public SseServerHostdService(HttpSseServer httpSseServer) {
_server = httpSseServer;
}
public async Task StartAsync(CancellationToken cancellationToken) {
await Task.Run(() => {
bool result= _server.Start();
});
} public async Task StopAsync(CancellationToken cancellationToken) {
await _server.Stopping();
}
}
  1. 修改 Index.cshtml ,实现 EventSource,成为比分直播页面

Index.cshtml:

@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
@section Scripts{
<script>
const eventSource = new EventSource("http://127.0.0.1:9111/msg/");
eventSource.onmessage = function (event) {
if (event.data) {
//document.getElementById('content').innerHTML += event.data ;
const status = JSON.parse(event.data);
document.getElementById('score1').innerHTML = status.score1;
document.getElementById('score2').innerHTML = status.score2;
if (status.lastaction) {
document.getElementById('content').innerHTML += status.lastaction;
}
}
}
</script>
} <div class="text-center">
<h1 class="display-4">Welcome</h1>
<div style="font-size:40px">
<p >
<span id="score1">0</span>
<span>-</span>
<span id="score2">0</span>
</p>
</div>
<div id="content" style="width:800px;height:600px;overflow:scroll;">
</div>
</div>

4.创建 Manage.cshtml 页面,比分输入功能:

Manage.cshtml:

@page
@model CompetitionLive.Pages.ManageModel
@{ } <form method="post">
<p>
<label for="number" asp-for="Score1"></label>
<input type="number" asp-for="Score1" id="score1" />
</p>
<p>
<label for="number" asp-for="Score2"></label>
<input type="number" asp-for="Score2" />
</p>
<p>
<label for="text2" asp-for="LastAction"></label>
<input type="text" asp-for="LastAction" />
</p>
<p><input type="submit" /></p>
</form>

Manage.cshtml.cs:

public class ManageModel : PageModel
{
private readonly HttpSseServer _httpSseServer;
public ManageModel( HttpSseServer httpSseServer) {
_httpSseServer = httpSseServer;
}
public int Score1 { get; set; } = 0;
public int Score2 { get; set; } = 0;
public string LastAction { get; set; }
public void OnGet()
{ } public void OnPost(int score1,int score2,string lastAction) {
Dictionary<string, object> dict = new Dictionary<string, object>();
dict["score1"] = score1;
dict["score2"] = score2;
dict["lastaction"] = lastAction+"<br />"; _httpSseServer.StreamManagement.All.PushSseMsg(Newtonsoft.Json.JsonConvert.SerializeObject(dict));
}
}

5.启动运行

效果:

附源码地址:TinyHttpSSE.Dotnet.Demo\CompetitionLive

基于 SSE、asp.net core razor 实现比分Live的更多相关文章

  1. ASP.NET Core - Razor 页面简介

    简介 随着ASP.NET Core 2 即将来临,最热门的新事物是Razor页面.在之前的一篇文章中,我们简要介绍了ASP.NET Core Razor 页面. Razor页面是ASP.NET Cor ...

  2. ASP.NET Core Razor 页面使用指南

    ASP.NET Core Razor 页面作为 ASP.NET Core 2.0的一部分发布,它是基于页面的全新的Web开发框架.如果您想学习如何使用 ASP.NET Core Razor 页面,可以 ...

  3. 学习ASP.NET Core Razor 编程系列一

    一. 概述 .NET Core 1.0发布的时候就想进行学习的,不过根据微软的以往的发布规律1.0版可以认为是大众测试版,2.0才算稳定.现在2.1都已经发布了预览版,之前对其"不稳定&qu ...

  4. 学习ASP.NET Core Razor 编程系列九——增加查询功能

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  5. ASP.Net Core Razor+AdminLTE 小试牛刀

    AdminLTE 一个基于 bootstrap 的轻量级后台模板,这个前端界面个人感觉很清爽,对于一个大后端的我来说,可以减少较多的时间去承担前端的工作但又必须去独立去完成一个后台系统开发的任务,并且 ...

  6. 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  7. ASP.NET Core - Razor 页面介绍

    简介 随着ASP.NET Core 2 即将来临,最热门的新事物是Razor页面.在之前的一篇文章中,我们简要介绍了ASP.NET Core Razor 页面. Razor页面是ASP.NET Cor ...

  8. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  9. ASP.NET Core - Razor页面之Handlers处理方法

    简介 在前一篇文章中,我们讨论了Razor页面.今天我们来谈谈处理方法(Handlers). 我们知道可以将代码和模型放在 .cshtml 文件里面或与 .cshtml 匹配的 .cshtml.cs ...

  10. ASP.NET Core Razor中处理Ajax请求

    如何ASP.NET Core Razor中处理Ajax请求 在ASP.NET Core Razor(以下简称Razor)刚出来的时候,看了一下官方的文档,一直没怎么用过.今天闲来无事,准备用Rozor ...

随机推荐

  1. 洛谷P2701 [USACO5.3] 巨大的牛棚Big Barn 题解

    怎么题解全是清一色的 dp?可以用笛卡尔树啊(虽然麻烦了很多,但是我热爱)! 题目传送门. 笛卡尔树的介绍 笛卡尔树,是一种二叉搜索树,它满足如下条件: 每个节点的编号满足二叉搜索树的性质. 每个节点 ...

  2. C#之 Dictionary 详解

    基本概念 Dictionary<TKey, TValue>是C#中用于存储键值对集合的泛型类,属于System.Collections.Generic命名空间.它允许使用键(Key)来访问 ...

  3. openpyxl 写入字典

    def write(self,data_path, sheetname,value): index = len(value) workbook = openpyxl.Workbook() sheet ...

  4. postgresql 查询表结构

    sql查询 SELECT A.attnum, ( SELECT description FROM pg_catalog.pg_description WHERE objoid = A.attrelid ...

  5. laravel引用文件资源

    <link rel="stylesheet" href="{{ asset('css/swiper.min.css') }}"> <link ...

  6. Redis 过期键删除和内存淘汰策略【Redis 系列之四】

    〇.前言 对于 Redis 服务器来说,内存资源非常宝贵,如果一些过期键一直不被删除,就会造成资源浪费. 那么,本文将结合博主收集的资料,简单介绍下过期键删除.内存淘汰两个策略,仅供参考. 博主 Re ...

  7. nodejs目录与文件遍历

    路径相关函数 path.basename('/foo/bar/baz/asdf/quux.html'); // Returns: 'quux.html' path.basename('/foo/bar ...

  8. 探秘Transformer系列之(25)--- KV Cache优化之处理长文本序列

    探秘Transformer系列之(25)--- KV Cache优化之处理长文本序列 目录 探秘Transformer系列之(25)--- KV Cache优化之处理长文本序列 0x00 概述 0x0 ...

  9. Robot Framework全局变量集合取值

    在一次测试中,可能需要使用多个不同的会员,即需要多注册多个会员.如此配置单一参数化是无法满足对所有注册会员名的统一管理,这里引入参数变量组来实现 步骤如下: 1.脚本目录点击总目录,右键点击New R ...

  10. Robot Framework全局变量设置

    脚本在每次执行的时候,自定义输入的内容,每次均需要手动去修改 比如,添加商品,上一次执行设置的商品名称为"商品1",这次再执行"商品1"就会导致冲突 如果仅仅是 ...