前言

最近在项目中用到了 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. API方式开发AI应用的三点总结

    1. 编程式prompt 让 AI 具备类似程序的运行逻辑.把大模型当CLR使用.与传统的角色扮演提示prompt相比,此方式所需的tokens数量更少,且输出结果的准确性更高 .示例如下: 2. 语 ...

  2. Stream4Graph:动态图上的增量计算

    作者:张奇 众所周知,当我们需要对数据做关联性分析的时候,一般会采用表连接(SQL join)的方式完成.但是SQL join时的笛卡尔积计算需要维护大量的中间结果,从而对整体的数据分析性能带来巨大影 ...

  3. 分布式锁—2.Redisson的可重入锁

    大纲 1.Redisson可重入锁RedissonLock概述 2.可重入锁源码之创建RedissonClient实例 3.可重入锁源码之lua脚本加锁逻辑 4.可重入锁源码之WatchDog维持加锁 ...

  4. linux系统测试磁盘IO速度 - fio使用

    ****** 很重要 很有用 很牛逼 的linux下的测试磁盘io速度的脚本 1 安装工具库 安装fio 首先,你需要安装fio.在不同的Linux发行版中,安装方法可能有所不同. fio可以通过命令 ...

  5. VScode美化

    RESULT:EVA-初号机 配色 主题效果 1. 需要的东西 vs code background 插件 custom CSS and JS loader 插件 一些png素材,推荐网址: http ...

  6. HIVE带中括号的列名取数

    某次取数,某表中有奇怪的字段名:pointchange_ygz_[yyyy],带了个中插号,用简单查询出错 select pointchange_ygz_[yyyy] as p from t 出错信息 ...

  7. EmlBuilder:一款超轻量级的EML格式电子邮件阅读和编辑工具

    EmlBuilder 是一款超轻量级的电子邮件阅读和编辑工具,针对EML格式的文件具有非常强大的解析和容错能力,可实现超文本邮件的编写,并具备内嵌图片的编辑功能.该工具内部使用EmlParse对电子邮 ...

  8. 【VMware VCF】解决 VCF 环境中组件用户密码过期问题。

    由于长时间没有启动 VCF 环境,现在在启动 SDDC Manager 组件后,UI 一直处于如下图所示的"初始化"状态.当时第一直觉就认为肯定是 VCF 环境组件的用户密码过期了 ...

  9. .NET 中的 Swagger 文档排序设置

    Swagger的API默认排序往往达不到效果,甚至设置了Action排序也没有作用.这里直接给出代码,关键在于 IDocumentFilter 实现. 注意 DocumentFilter 注册要放在尾 ...

  10. K8s Ingress, 你这个老6

    本文是有态度马甲的第185篇原创. 本文记录了k8s中核心对象Ingress的产生背景和实现机制. 我们都知道k8s Service是一种将Pods通过网络暴露出来的抽象,每个服务定义了一组有关Pod ...