最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#實(shí)現(xiàn) Server-sent Events的步驟

 更新時間:2021年01月07日 16:36:04   作者:yswenli  
這篇文章主要介紹了C#實(shí)現(xiàn) Server-sent Events的步驟,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下

基于http協(xié)議交互的推送方法大概方法如下:

  1. 輪詢(ajax),比較耗費(fèi)服務(wù)器資源。COMET方式(COMET 技術(shù)并不是 HTML 5 )
  2. websocket 雙向數(shù)據(jù)推送,靈活,功能強(qiáng)大
  3. Server-sent-event(簡稱SSE),單項(xiàng)數(shù)據(jù)推送(Server-sent Events 規(guī)范是 HTML 5 規(guī)范的一個組成部分)

這里我們研究一下SSE;

一、什么是SSE

Server-sent Events 規(guī)范是 HTML 5 規(guī)范的一個組成部分,具體的規(guī)范文檔見參考資源。該規(guī)范比較簡單,主要由兩個部分組成:第一個部分是服務(wù)器端與瀏覽器端之間的通訊協(xié)議,第二部分則是在瀏覽器端可供 JavaScript 使用的 EventSource 對象。通訊協(xié)議是基于純文本的簡單協(xié)議。服務(wù)器端的響應(yīng)的內(nèi)容類型是“text/event-stream”。響應(yīng)文本的內(nèi)容可以看成是一個事件流,由不同的事件所組成。每個事件由類型和數(shù)據(jù)兩部分組成,同時每個事件可以有一個可選的標(biāo)識符。不同事件的內(nèi)容之間通過僅包含回車符和換行符的空行(“\r\n”)來分隔。每個事件的數(shù)據(jù)可能由多行組成。嚴(yán)格地說,HTTP協(xié)議無法做到服務(wù)器主動推送信息。但是有一種變通的發(fā)光法,就是服務(wù)器向客戶端聲明,接下來要發(fā)送的是流信息,也就是說,發(fā)送的不是一次性的數(shù)據(jù)包,而是一個數(shù)據(jù)流,會連續(xù)不斷的發(fā)送過來。這是客戶端不會關(guān)閉連接,會一直等待服務(wù)器發(fā)過來的數(shù)據(jù)流,視頻播放就是這樣的例子。本質(zhì)上這種通信就是以流信息的方式,完成一次用時很長的下載。

二、SSE傳輸協(xié)議分析

了解了什么是SSE之后就發(fā)現(xiàn)這種模式針對后端開發(fā)來說是一個巨大的改進(jìn),可以像ajax一樣,卻比ajax節(jié)省資源;能實(shí)現(xiàn)websocket的服務(wù)器推送卻不需要更換協(xié)議和端口,就像寫一個特別點(diǎn)的api接口一樣方便。跟蹤一下sse的報文顯示

: this is a comment\n
reply: 3000\n
event: message\n
data: first\n\n
data: second\n\n
id: 100\n
event: myevent\n
data: third\n\n
id: 101\n
: this is a comment\n
data: fourth\n
data: fourth continue\n\n

接下就按如下來分析報文內(nèi)容:

類型為空白,表示該行是注釋,會在處理時被忽略。

類型為 data,表示該行包含的是數(shù)據(jù)。以 data 開頭的行可以出現(xiàn)多次。所有這些行都是該事件的數(shù)據(jù)。

類型為 event,表示該行用來聲明事件的類型。瀏覽器在收到數(shù)據(jù)時,會產(chǎn)生對應(yīng)類型的事件。

類型為 id,表示該行用來聲明事件的標(biāo)識符。

類型為 retry,表示該行用來聲明瀏覽器在連接斷開之后進(jìn)行再次連接之前的等待時間。

三、C#實(shí)現(xiàn)SSE服務(wù)端

SSE的內(nèi)容還是很簡潔的,了解了差不多了,現(xiàn)在開始做起來。

1.根據(jù)SSE規(guī)范對html的頭部進(jìn)行處理,主要就是添加text/event-stream類型,去掉緩存

 HttpContext.Current.Response.ContentType = "text/event-stream; charset=utf-8";
 HttpContext.Current.Response.SetHeader(ResponseHeaderType.CacheControl, "no-cache");
 HttpContext.Current.Response.SetHeader(ResponseHeaderType.KeepAlive, "timeout=5");
 HttpContext.Current.Response.Status = HttpStatusCode.OK;
 HttpContext.Current.Response.SendHeader(-1);

2.封裝SSE數(shù)據(jù)格式,SSE的數(shù)據(jù)都是采用UTF8進(jìn)行處理的

ServerSent(Encoding.UTF8.GetBytes($"id: {id?.Trim()}\nevent: {@event?.Trim()}\ndata: {SerializeHelper.Serialize(t)}\n\n"));

僅需二步就已經(jīng)完成了SSE服務(wù)端的處理了,下面是SAEA.MVC下面的一個完整封裝類EventStream

/****************************************************************************
*項(xiàng)目名稱:SAEA.MVC
*CLR 版本:4.0.30319.42000
*機(jī)器名稱:WALLE-PC
*命名空間:SAEA.MVC
*類 名 稱:EventStream
*版 本 號:V1.0.0.0
*創(chuàng)建人: yswenli
*電子郵箱:yswenli@outlook.com
*創(chuàng)建時間:2021/1/6 14:02:09
*描述:
*=====================================================================
*修改時間:2021/1/6 14:02:09
*修 改 人: yswenli
*版 本 號: V1.0.0.0
*描  述:
*****************************************************************************/
using SAEA.Common;
using SAEA.Common.Serialization;
using SAEA.Common.Threading;
using SAEA.Http.Model;
using System.Net;
using System.Text;

namespace SAEA.MVC
{
  /// <summary>
  /// SSE服務(wù)器事件流
  /// </summary>
  public class EventStream : ActionResult, IEventStream
  {
    /// <summary>
    /// 最后一次接收到的事件的標(biāo)識符
    /// </summary>
    public int LastEventID
    {
      get;
      private set;
    }

    /// <summary>
    /// SSE服務(wù)器事件流
    /// </summary>
    /// <param name="retry">指定瀏覽器重新發(fā)起連接的時間間隔</param>
    public EventStream(int retry = 3 * 1000)
    {
      this.ContentEncoding = Encoding.UTF8;

      if (HttpContext.Current.Request.Headers.ContainsKey("Last-Event-ID"))
      {
        if (int.TryParse(HttpContext.Current.Request.Headers["Last-Event-ID"], out int id))
        {
          LastEventID = id;
        }
      }

      HttpContext.Current.Response.ContentType = "text/event-stream; charset=utf-8";
      HttpContext.Current.Response.SetHeader(ResponseHeaderType.CacheControl, "no-cache");
      HttpContext.Current.Response.SetHeader(ResponseHeaderType.KeepAlive, "timeout=5");
      HttpContext.Current.Response.Status = HttpStatusCode.OK;
      HttpContext.Current.Response.SendHeader(-1);

      //心跳
      var pong = $"SAEAServer PONG {DateTimeHelper.Now:yyyy:MM:dd HH:mm:ss.fff}";

      TaskHelper.LongRunning(() =>
      {
        ServerSent(Encoding.UTF8.GetBytes($": {SerializeHelper.Serialize(pong)}\n\n"));
      }, 1000);

      //斷開重連時長
      ServerSent(Encoding.UTF8.GetBytes($"retry: {retry}\n\n"));
    }
    /// <summary>
    /// 發(fā)送通知
    /// </summary>
    /// <param name="str"></param>
    /// <param name="event"></param>
    /// <param name="id"></param>
    public void ServerSent<T>(T t, string @event = "message", string id = "") where T : class
    {
      if (t != null)
        ServerSent(Encoding.UTF8.GetBytes($"id: {id?.Trim()}\nevent: {@event?.Trim()}\ndata: {SerializeHelper.Serialize(t)}\n\n"));
    }
    /// <summary>
    /// 發(fā)送通知
    /// </summary>
    /// <param name="content"></param>
    public void ServerSent(byte[] content)
    {
      HttpContext.Current.Response.SendData(content);
    }
  }
}

3.使用EventStream類快速實(shí)現(xiàn)服務(wù)器推送

將EventStream集成到Controller中,那么在業(yè)務(wù)繼承類中就可以直接使用封裝好的SSE功能了,如下例:

/****************************************************************************
*項(xiàng)目名稱:SAEA.MVCTest.Controllers
*CLR 版本:4.0.30319.42000
*機(jī)器名稱:WALLE-PC
*命名空間:SAEA.MVCTest.Controllers
*類 名 稱:EventStreamController
*版 本 號:V1.0.0.0
*創(chuàng)建人: yswenli
*電子郵箱:yswenli@outlook.com
*創(chuàng)建時間:2021/1/6 13:57:09
*描述:
*=====================================================================
*修改時間:2021/1/6 13:57:09
*修 改 人: yswenli
*版 本 號: V1.0.0.0
*描  述:
*****************************************************************************/
using SAEA.MVC;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace SAEA.MVCTest.Controllers
{
  /// <summary>
  /// EventStreamController
  /// </summary>
  public class EventStreamController : Controller
  {
    /// <summary>
    /// 發(fā)送通知
    /// </summary>
    /// <returns></returns>
    public ActionResult SendNotice()
    {
      try
      {
        var es = GetEventStream();

        for (int i = 0; ; i++)
        {
          var str = $"SAEA.MVC EventStream Test {i}";

          es.ServerSent(str);

          Thread.Sleep(1000);
        }
      }
      catch (Exception ex)
      {

      }
      return Empty();
    }
  }
}

四、驗(yàn)證SSE功能

了解了SSE技術(shù)相關(guān)理論,并按理論封裝了EventStream,最后使用EventStream實(shí)現(xiàn)了一個推送測試邏輯,接下來就是使用js的EventSource對象在瀏覽器中來驗(yàn)證了。

創(chuàng)建一個網(wǎng)頁,在html中的js中輸入:

     var source = new EventSource("/api/eventstream/sendnotice");
     source.onmessage = function (event) {
       document.getElementById("eventstream").innerHTML += event.data + "<br/>";
     };

 打開瀏覽器的工發(fā)者工具,在網(wǎng)絡(luò)選項(xiàng)中查看詳細(xì)內(nèi)容:

以上就是C#實(shí)現(xiàn) Server-sent Events的步驟的詳細(xì)內(nèi)容,更多關(guān)于C#實(shí)現(xiàn) Server-sent Events的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#使用Ado.net讀取Excel表的方法

    C#使用Ado.net讀取Excel表的方法

    這篇文章主要介紹了C#使用Ado.net讀取Excel表的方法,涉及C#使用OLEDB操作Excel的方法,需要的朋友可以參考下
    2015-04-04
  • C#使用FileInfo和DirectoryInfo類來執(zhí)行文件和文件夾操作

    C#使用FileInfo和DirectoryInfo類來執(zhí)行文件和文件夾操作

    System.IO.FileInfo?和?System.IO.DirectoryInfo?是C#中用于操作文件和文件夾的類,它們提供了許多有用的方法和屬性來管理文件和文件夾,這篇文章主要介紹了C#使用FileInfo和DirectoryInfo類來執(zhí)行文件和文件夾操作,需要的朋友可以參考下
    2023-08-08
  • c#連接access數(shù)據(jù)庫操作類分享

    c#連接access數(shù)據(jù)庫操作類分享

    本文介紹了c#連接access數(shù)據(jù)庫的方法,可以執(zhí)行刪除、更新、插入等操作,大家參考使用吧
    2014-01-01
  • C#生成防偽碼的思路及源碼分享

    C#生成防偽碼的思路及源碼分享

    生成防偽碼其實(shí)挺簡單,但是如果要考慮效率和不重復(fù)的話,就需要稍微動動腦子了,下面我來說說我的思路及源碼
    2014-06-06
  • 一文帶你快速學(xué)會C#中WinForm框架的使用詳解

    一文帶你快速學(xué)會C#中WinForm框架的使用詳解

    WinForm是一門非常經(jīng)濟(jì)實(shí)惠的技術(shù),就是說,可以在短時間內(nèi)學(xué)會,并迅速借此進(jìn)行項(xiàng)目開發(fā)。本文就來和大家聊聊WinForm框架的使用方法,希望對大家有所幫助
    2023-02-02
  • C#實(shí)現(xiàn)虛擬鍵盤的實(shí)例詳解

    C#實(shí)現(xiàn)虛擬鍵盤的實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)虛擬鍵盤,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • javascript函數(shù)中執(zhí)行c#函數(shù)的方法

    javascript函數(shù)中執(zhí)行c#函數(shù)的方法

    這篇文章主要介紹了javascript和c#函數(shù)和變量互相調(diào)用的方法,大家參考使用吧
    2014-01-01
  • C#導(dǎo)出數(shù)據(jù)到Excel文件的方法

    C#導(dǎo)出數(shù)據(jù)到Excel文件的方法

    這篇文章主要介紹了C#導(dǎo)出數(shù)據(jù)到Excel文件的方法,涉及C#操作Excel的相關(guān)技巧,非常具有實(shí)用價值,需要的朋友可以參考下
    2015-04-04
  • C#和lua相互調(diào)用的方法教程

    C#和lua相互調(diào)用的方法教程

    lua是一種腳本語言,可以方便的移植到各種宿主語言中,并且可以支持熱更新,在游戲開發(fā)中也能當(dāng)做主要的語言來編寫游戲的邏輯,所以這篇文章主要給大家介紹了關(guān)于C#和lua相互調(diào)用的方法教程,需要的朋友可以參考下。
    2017-11-11
  • WPF使用HLSL實(shí)現(xiàn)百葉窗動畫效果

    WPF使用HLSL實(shí)現(xiàn)百葉窗動畫效果

    百葉窗動畫是制作PPT時常用的動畫之一,本文將通過實(shí)現(xiàn)百葉窗動畫效果的例子介紹在WPF中如何使用ShaderEffect,感興趣的小伙伴可以了解一下
    2023-09-09

最新評論

寿光市| 木里| 武威市| 岳阳市| 钟山县| 吉林省| 红安县| 泾川县| 哈尔滨市| 龙川县| 同德县| 城口县| 白银市| 通化市| 双城市| 扎兰屯市| 浦江县| 木兰县| 弋阳县| 肥西县| 海城市| 清河县| 慈溪市| 突泉县| 横峰县| 东丽区| 昌宁县| 清流县| 南平市| 苏尼特右旗| 平塘县| 靖江市| 鄱阳县| 蓝田县| 虞城县| 车致| 桂东县| 大港区| 温州市| 年辖:市辖区| 鹤山市|