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)文章希望大家以后多多支持腳本之家!
- Python使用WebSocket和SSE實(shí)現(xiàn)HTTP服務(wù)器消息推送方式
- chatGPT前端流式輸出js實(shí)現(xiàn)三種方法—fetch、SSE、websocket
- Websocket的用法及常見(jiàn)應(yīng)用場(chǎng)景
- SpringBoot實(shí)現(xiàn)SSE(Server-Sent?Events)的完整指南
- Springboot?實(shí)現(xiàn)Server-Sent?Events的項(xiàng)目實(shí)踐
- Spring Boot中使用Server-Sent Events (SSE) 實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)推送教程
- Spring Boot中使用SSE(Server-Sent Events)實(shí)現(xiàn)聊天功能:替代websocket服務(wù)器推送
相關(guān)文章
C#結(jié)合JavaScript對(duì)Web控件進(jìn)行數(shù)據(jù)輸入驗(yàn)證的實(shí)現(xiàn)方法
在 Web 應(yīng)用的錄入界面,數(shù)據(jù)驗(yàn)證是一項(xiàng)重要的實(shí)現(xiàn)功能,數(shù)據(jù)驗(yàn)證是指確認(rèn) Web 控件輸入或選擇的數(shù)據(jù),本文我們將介紹如何通過(guò)C# 后端及JavaScript 前端對(duì) Web 控件進(jìn)行數(shù)據(jù)輸入有效性的驗(yàn)證,感興趣的朋友可以參考一下2024-05-05
C#讀取數(shù)據(jù)庫(kù)返回泛型集合詳解(DataSetToList)
本篇文章主要是對(duì)C#讀取數(shù)據(jù)庫(kù)返回泛型集合(DataSetToList)進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01
unity實(shí)現(xiàn)鼠標(biāo)跟隨(ITween)
這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)鼠標(biāo)跟隨,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
C#把數(shù)組中的某個(gè)元素取出來(lái)放到第一個(gè)位置的實(shí)現(xiàn)方法
這篇文章主要介紹了C#把數(shù)組中的某個(gè)元素取出來(lái)放到第一個(gè)位置的實(shí)現(xiàn)方法,涉及C#針對(duì)數(shù)組的常見(jiàn)操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-12-12
C#使用checkedListBox1控件鏈接數(shù)據(jù)庫(kù)的方法示例
這篇文章主要介紹了C#使用checkedListBox1控件鏈接數(shù)據(jù)庫(kù)的方法,結(jié)合具體實(shí)例形式分析了數(shù)據(jù)庫(kù)的創(chuàng)建及checkedListBox1控件連接數(shù)據(jù)庫(kù)的相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
C#使用Socket實(shí)現(xiàn)發(fā)送和接收?qǐng)D片的方法
這篇文章主要介紹了C#使用Socket實(shí)現(xiàn)發(fā)送和接收?qǐng)D片的方法,涉及C#操作socket發(fā)送與接收文件的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04

