C#實(shí)現(xiàn)SSE(Server-Sent Events)服務(wù)端和客戶端的示例代碼
效果圖
服務(wù)端不停發(fā)送當(dāng)前時(shí)間。
服務(wù)端代碼:
using System; using System.Collections.Generic; using System.Net; using System.Text; using System.Threading; namespace SSEserver { class Program { static void Main(string[] args) { HttpListener listener = new HttpListener(); listener.Prefixes.Add("http://localhost:8080/"); listener.Start(); Console.WriteLine("Server is running..."); while (true) { HttpListenerContext context = listener.GetContext(); ThreadPool.QueueUserWorkItem((_) => { SendEvent(context); }); } } static void SendEvent(HttpListenerContext context) { try { context.Response.ContentType = "text/event-stream"; context.Response.StatusCode = 200; context.Response.Headers.Add("Cache-Control", "no-cache"); context.Response.Headers.Add("Connection", "keep-alive"); while (true) { string message = $"data: {DateTime.Now.ToString("HH:mm:ss")}\n\n"; byte[] bytes = Encoding.UTF8.GetBytes(message); context.Response.OutputStream.Write(bytes, 0, bytes.Length); context.Response.OutputStream.Flush(); Thread.Sleep(1000); // 每秒發(fā)送一次消息 } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } finally { context.Response.Close(); } } } }
客戶端不停接收服務(wù)端發(fā)送的時(shí)間。
客戶端代碼:
using System; using System.IO; using System.Net; using System.Text; namespace SSEclient { class Program { static async Task Main(string[] args) { string url = "http://localhost:8080/sse_endpoint"; // SSE endpoint URL using (HttpClient client = new HttpClient()) { var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Add("Accept", "text/event-stream"); using (HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); using (var responseStream = await response.Content.ReadAsStreamAsync()) using (var reader = new System.IO.StreamReader(responseStream)) { while (!reader.EndOfStream) { string line = await reader.ReadLineAsync(); if (!string.IsNullOrWhiteSpace(line)) { Console.WriteLine(line); // Handle the received SSE event here } } } } } } } }
方法補(bǔ)充
除了上文的方法,小編還為大家整理了其他C#實(shí)現(xiàn)SSE(Server-Sent Events)的方法,希望對(duì)大家有所幫助
C# MVC 實(shí)現(xiàn)Server-Sent Events(ApiController案例)
(瀏覽器端) JS代碼:
// 建立ServerSentEvents(服務(wù)器向?yàn)g覽器推送信息,簡(jiǎn)稱SSE) $(function () { if (typeof (EventSource) !== "undefined") { // 展示服務(wù)器推送內(nèi)容的DOM var container = document.getElementById("SseContainer"); // 建立SSE通道 var es = new EventSource("/api/ServerSentEvents/BuildingSse"); // 監(jiān)聽(tīng)SSE通道open事件 es.onopen = function (event) { container.innerHTML += "open<br/>"; } // 監(jiān)聽(tīng)SSE接收到的服務(wù)端消息 es.onmessage = function (event) { container.innerHTML += event.data + "<br/>"; }; // 監(jiān)聽(tīng)SSE通道error事件 es.onerror = function (event) { container.innerHTML += "error<br/>"; es.close(); } } else { console.log("瀏覽器不支持ServerSentEvents接口!"); } })
(服務(wù)器端)C# MVC Controller代碼:
using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Web.Http; namespace CabinetMS.Controllers.WebApi { /// <summary> /// 自定義的SSE消息對(duì)象實(shí)體 /// </summary> public class SseMessageObject { public string MsgId { get; set; } public string MsgData { get; set; } } /// <summary> /// 以請(qǐng)求方式建立SSE通道 /// </summary> [RoutePrefix("api/ServerSentEvents")] public class ServerSentEventController : ApiController { // 接收瀏覽器請(qǐng)求,建立ServerSentEvents通道 [HttpGet, Route("BuildingSse")] public System.Net.Http.HttpResponseMessage BuildingSse(HttpRequestMessage request) { System.Net.Http.HttpResponseMessage response = request.CreateResponse(); response.Content = new System.Net.Http.PushStreamContent((Action<Stream, HttpContent, TransportContext>)WriteToStream, new MediaTypeHeaderValue("text/event-stream")); return response; } private static readonly ConcurrentDictionary<StreamWriter, StreamWriter> _streammessage = new ConcurrentDictionary<StreamWriter, StreamWriter>(); public void WriteToStream(Stream outputStream, HttpContent content, TransportContext context) { StreamWriter streamwriter = new StreamWriter(outputStream); _streammessage.TryAdd(streamwriter, streamwriter); } // 建立SSE通道后,其他Controller或程序調(diào)用此方法,可以向?yàn)g覽器端主動(dòng)推送消息 public static void SendSseMsg(SseMessageObject sseMsg) { MessageCallback(sseMsg); } // 設(shè)置向?yàn)g覽器推送的消息內(nèi)容 private static void MessageCallback(SseMessageObject sseMsg) { foreach (var subscriber in _streammessage.ToArray()) { try { subscriber.Value.WriteLine(string.Format("id: {0}\n", sseMsg.MsgId)); subscriber.Value.WriteLine(string.Format("data: {0}\n\n", sseMsg.MsgData)); subscriber.Value.Flush(); } catch { StreamWriter streamWriter; _streammessage.TryRemove(subscriber.Value, out streamWriter); } } } } }
(服務(wù)器端)成功建立SSE通道后,向?yàn)g覽器推送消息:
// 服務(wù)端向網(wǎng)頁(yè)端推送告警信息 var sseMsg = new SseMessageObject(); sseMsg.MsgId = "1101"; sseMsg.MsgData = "自定義告警消息"; ServerSentEventController.SendSseMsg(sseMsg);
到此這篇關(guān)于C#實(shí)現(xiàn)SSE(Server-Sent Events)服務(wù)端和客戶端的示例代碼的文章就介紹到這了,更多相關(guān)C# SSE服務(wù)端和客戶端內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#使用DevExpress中的XtraCharts控件實(shí)現(xiàn)圖表
這篇文章介紹了C#使用DevExpress中的XtraCharts控件實(shí)現(xiàn)圖表的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05c# asp .net 動(dòng)態(tài)創(chuàng)建sql數(shù)據(jù)庫(kù)表的方法
c# asp .net 動(dòng)態(tài)創(chuàng)建sql數(shù)據(jù)庫(kù)表的方法,需要的朋友可以參考一下2013-04-04C#使用正則表達(dá)式實(shí)現(xiàn)常見(jiàn)的格式驗(yàn)證
這篇文章主要為大家詳細(xì)介紹了C#如何使用正則表達(dá)式實(shí)現(xiàn)常見(jiàn)的格式驗(yàn)證,例如:電話號(hào)碼、密碼、郵編等,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01C#使用Winform編寫一個(gè)圖片預(yù)覽器管理
這篇文章主要為大家詳細(xì)介紹了C#如何使用Winform編寫一個(gè)通用圖片預(yù)覽器管理,包含滾輪放大縮小,剪切,下一頁(yè),方向變化等,需要的可以參考下2024-02-02Unity3d實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)背景
這篇文章主要為大家詳細(xì)介紹了Unity3d實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)背景,一個(gè)完整的商店廣告牌組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01