ASP.net使用C#实现HTML5的server-sent events

bluebaby88 bluebaby88 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
前几天因客户的需要,希望把原来的监控系统从c/s模式变成b/s模式,其他的都好办,但是实时告警和实时数据处理是个问题。采用以前web的轮询技术可能导致多个客户端的告警和数据不一致的问题,于是考虑采用web推送技术。
web推送,在网上查了一下,有多种方式,比如HTML5的server-sent events技术、HTML5的WebSocket技术、基于comet服务器推送技术等等,很多。
考虑到客户的浏览器是Google浏览器或FireFox浏览器,所以使用HTML5的技术,因为告警数据是从服务器推送过来的,不需要在接收到后进行处理然后回送的情况,所以使用半双工方式的server-sent events来实现。
编译环境使用VS2010,语言C#
以下是采用该技术的验证过程:
首先新建一个名称为TieTaOMC的ASP.net工程
然后打开Global.asax.cs文件

在文件内添加CSubscrib类,用来订阅推送消息

CSubscrib类里结构介绍
Dictionary<long, HttpResponse> m_Response的字典私有成员变量,又来存放订阅的Response对象,字典的Key是随机生成的长整形数,value是HttpResponse类型的Response对象。
addResponse公有方法,用来添加要订阅的Response对象
delResponse公有方法,用来删除已订阅的Response对象
sendSubscribMessage公有方法,用来向某个已订阅的Response对象推送消息
sendSubscribMessageToAllResponses公有方法,用来向所有的已订阅的Response对象推送消息

在Global类的Application_Start方法中添加如下内容

//告警更新订阅
Application.Add("AlarmsUpdateSubscrib", new CSubscrib());

//实时数据更新订阅
Application.Add("DatasUpdateSubscrib", new CSubscrib());


用来保存告警更新订阅类实例和实时数据更新订阅类实例。

以下为Global.asax.cs内容:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

namespace TieTaOMC
{
/// <summary>
/// 订阅类
/// </summary>
public class CSubscrib
{
/// <summary>
/// 订阅响应信息对象字典
/// </summary>
private Dictionary<long, HttpResponse> m_Response;

/// <summary>
/// 订阅类实例
/// </summary>
public CSubscrib()
{
m_Response = new Dictionary<long, HttpResponse>();
}

/// <summary>
/// 添加订阅
/// </summary>
/// <param name="lResponseID">响应信息对象编号</param>
/// <param name="htpResponse">响应信息对象</param>
/// <returns>是否成功</returns>
public bool addResponse(long lResponseID, HttpResponse htpResponse)
{
bool bReturn = false;

if (0 < lResponseID && null != htpResponse)
{
if (!m_Response.ContainsKey(lResponseID))
{
m_Response.Add(lResponseID, htpResponse);
bReturn = true;
}
}
return bReturn;
}

/// <summary>
/// 删除订阅
/// </summary>
/// <param name="lResponseID">响应信息对象编号</param>
/// <returns>是否成功</returns>
public bool delResponse(long lResponseID)
{
bool bReturn = false;

if (0 < lResponseID)
{
if (m_Response.ContainsKey(lResponseID))
{
//m_Response[lResponseID].Close();
bReturn = m_Response.Remove(lResponseID);
}
}
return bReturn;
}

/// <summary>
/// 发送订阅信息
/// </summary>
/// <param name="lResponseID">响应信息对象编号</param>
/// <param name="sMessage">信息字符串</param>
/// <param name="bCheckExsist">是否检查存在,默认为不检查</param>
/// <returns>是否成功</returns>
public bool sendSubscribMessage(long lResponseID, string sMessage, string sObjID, bool bCheckExsist = false)
{
bool bReturn = false;

if (0 < lResponseID && null != sMessage && 0 < sMessage.Length)
{
bool bExsist = true;
if (bCheckExsist)
{
bExsist = m_Response.ContainsKey(lResponseID);
}
if (bExsist)
{
try
{
HttpResponse htpResponse = m_Response[lResponseID];
htpResponse.Write("data: " + sObjID + "\n");
htpResponse.Write("data: " + sMessage + "\n\n");
htpResponse.Flush();
}
catch (System.Exception ex)
{
string sError = ex.Message;
sError = "";
}
bReturn = true;
}
}
return bReturn;
}

/// <summary>
/// 向所有的订阅响应信息对象发送信息
/// </summary>
/// <param name="sMessage"></param>
/// <returns></returns>
public bool sendSubscribMessageToAllResponses(string sMessage, string sObjID)
{
bool bReturn = false;

if (null != sMessage && 0 < sMessage.Length)
{
bReturn = true;
foreach (long lResponseID in m_Response.Keys)
{
sendSubscribMessage(lResponseID, sMessage, sObjID);
}
}
return bReturn;
}
}

public class Global : System.Web.HttpApplication
{

void Application_Start(object sender, EventArgs e)
{
// 在应用程序启动时运行的代码

//告警更新订阅
Application.Add("AlarmsUpdateSubscrib", new CSubscrib());

//实时数据更新订阅
Application.Add("DatasUpdateSubscrib", new CSubscrib());
}

void Application_End(object sender, EventArgs e)
{
// 在应用程序关闭时运行的代码

}

void Application_Error(object sender, EventArgs e)
{
// 在出现未处理的错误时运行的代码

}

void Session_Start(object sender, EventArgs e)
{
// 在新会话启动时运行的代码

}

void Session_End(object sender, EventArgs e)
{
// 在会话结束时运行的代码。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
// 或 SQLServer,则不会引发该事件。

}
}
}

...全文
评论 5
收藏 已收藏
分享
返回顶部
bluebaby88
.NET社区 62,272 成员 668,968 内容