数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

SignalR与WCF双工模式结合实现服务端数据直推浏览器端


发布日期:2023年08月10日
 
SignalR与WCF双工模式结合实现服务端数据直推浏览器端

之前开发基于WinForm监控的软件服务端基于Wcf实现里面涉及双工模式在客户端里面采用心跳包机制保持与服务端链接现在有了新需求需要开发网页版形式所以怎么保持与服务端链接是重要点由于数据量比较大所以不能采用客户端发起请求不断轮询的方式参考各种资料后使用SignalR主要是支持WebSockets通信并且Hub链接方式解决了realtime 信息交换的功能问题

下图是MSDN关于解释

Hub:提供与连接到 Hub 的 SignalR 连接进行通信的方法

Globalasax

using System;

using SystemCollectionsGeneric;

using SystemLinq;

using SystemWeb;

using SystemWebSecurity;

using SystemWebSessionState;

using SystemWebRouting;

using MicrosoftAspNetSignalR;

namespace LMSCitySignalR

{

public class Global : SystemWebHttpApplication

{

protected void Application_Start(object sender EventArgs e)

{

RouteTableRoutesMapHubs();

}

protected void Session_Start(object sender EventArgs e)

{

}

protected void Application_BeginRequest(object sender EventArgs e)

{

}

protected void Application_AuthenticateRequest(object sender EventArgs e)

{

}

protected void Application_Error(object sender EventArgs e)

{

}

protected void Session_End(object sender EventArgs e)

{

}

protected void Application_End(object sender EventArgs e)

{

}

}

}

页面代码

<%@ Page Language=C# AutoEventWireup=true CodeBehind=CityLmsClientaspxcs Inherits=LMSCitySignalRCityLmsClient %>

<meta httpequiv=XUACompatible content=IE=edge />

<!DOCTYPE html>

<html xmlns=>

<head runat=server>

<meta httpequiv=ContentType content=text/html; charset=utf />

<title>LH CityLMS Client</title>

</head>

<body>

<div id=dvMsg></div>

Client Mac Address:

<input id=txtMac type=text value=:E::DA:C:D />

<input id=btnCnLmsSvr type=button value=Connect CityLms Server />

<br>

User Name:<input id=txtUserName type=text value=admin />

User Password:<input id=txtUserPassword type=password value=admin />

<input id=btnLogin type=button value=Login />

<br>

<input id=btnMonitorClientChanel type=button value=MonitorClientChanel />

<br />

<input id=btnEmergencyControl type=button value=Emergency Control />

<br />

<input id=btnDisConSvr type=button value=DisConnect Svr />

<script src=Scripts/jqueryjs type=text/javascript></script>

<script src=Scripts/jsonjs type=text/javascript></script>

<script src=Scripts/jquerysignalRjs type=text/javascript></script>

<script src=/signalr/hubs type=text/javascript></script>

<script type=text/javascript>

$(function () {

/*

* 参考链接:

*· Persistent Connection(HTTP持久链接)持久性连接用来解决长时间连接的能力而且还可以由客户端主动向服务器要求数据而服务器端也不需要实现太多细节只需要处理 PersistentConnection 内所提供的五个事件OnConnected OnReconnected OnReceived OnError 和 OnDisconnect 即可

*· Hub信息交换器用来解决 realtime 信息交换的功能服务器端可以利用 URL 来注册一个或多个 Hub只要连接到这个 Hub就能与所有的客户端共享发送到服务器上的信息同时服务器端可以调用客户端的脚本不过它背后还是不离 HTTP 的标准所以它看起来神奇但它并没有那么神奇只是 JavaScript 更强强到可以用像 eval() 或是动态解释执行的方式允许 JavaScript 能够动态的加载与执行方法调用而己

*/

/*链接对应server端Hub对象*/

var cityLmsClient = nnectioncityLmsClientHub;

citytServerResult = function (name message) {

$(#dvMsg)append(<li><strong> + (new Date())toLocaleTimeString() + Client Mac Address + name

+ Connect CityLms Server Result: + message + </strong></li>);

};

/*断开连接消息提示*/

cityLmsClientclientdisConSvr = function (message) {

alert(message);

};

/*操作消息提示*/

cityLmsClientclientoperateMsg = function (message) {

$(#dvMsg)append(<li><strong> + (new Date())toLocaleTimeString() + + message + </strong></li>);

};

nnectionhubstart()done(function () {

/*链接wcf Server*/

$(#btnCnLmsSvr)click(function () {

citynServer($(#txtMac)val());

});

/*应急操作*/

$(#btnEmergencyControl)click(function () {

cityLmsClientserveremergencyControl();

});

/*用户登录*/

$(#btnLogin)click(function () {

cityLmsClientserveruserLogin($(#txtUserName)val() $(#txtUserPassword)val());

});

/*启动心跳包以保持与wcf Server连接*/

$(#btnMonitorClientChanel)click(function () {

cityLmsClientservermonitorClientChanel();

});

/*断开连接*/

$(#btnDisConSvr)click(function () {

cityLmsClientserverdisConnectSvr();

});

});

/*日志显示*/

nnectionhublogging = true;

});

</script>

</body>

</html>

cityLmsClientHubcs代码

using System;

using SystemCollectionsGeneric;

using SystemDiagnostics;

using SystemLinq;

using SystemReflection;

using SystemServiceModel;

using SystemThreading;

using SystemWeb;

using DL_LMS_ServerDefaultShared;

using DL_LMS_ServerServiceDataModelParameter;

using DL_LMS_ServerServiceDataModelResult;

using MicrosoftAspNetSignalR;

namespace LMSCitySignalR

{

public class cityLmsClientHub : Hub

{

ServiceCallBack serCallBack = null;

/// <summary>

/// 应急操作回调

/// </summary>

/// <param name=sender></param>

/// <param name=e></param>

private void RealTimeCabChCallBackMessage_Event(object sender LMSClientNotifiedEventArgs e)

{

COptRealTimeCabChResult optCabChresult = eNotifiedMessage as COptRealTimeCabChResult;

string _sMsg = stringFormat({}CabID:{}byChActType:{}byChActType:{}byChActType:{}byChActType:{}byChActType:{}byChActType:{}CtuLockStatus:{}

DateTimeNowToShortTimeString()

optCabChresultCabID

optCabChresultbyChActType

optCabChresultbyChActType

optCabChresultbyChActType

optCabChresultbyChActType

optCabChresultbyChActType

optCabChresultbyChActType

optCabChresultCtuLockStatus);

ClientsClient(ContextConnectionId)OperateMsg(_sMsg);

ClientsClient(ContextConnectionId)OperateMsg(==========================end======================);

}

public void Hello()

{

ClientsAllhello();

}

private static bool bIsConnect = false;

private static string sMacAddress = null;

private static string sUserName = null;

private static string sUserPassword = null;

/// <summary>

///链接wcf Server

/// </summary>

/// <param name=clientMacAddress>mac地址</param>

/// <returns></returns>

private CommunResult ConnService(string clientMacAddress)

{

CommunResult result = new CommunResult();

try

{

SvrRetMessage svrMessage = ClientComServiceFactoryGetClientServiceFactoryGetClientComServiceConnect(clientMacAddress);

if (!svrMessageExcuResult)

{

resultMessage = svrMessageMessage;

resultCommunState = CommStateNoRegister;

}

resultCommunState = CommStateScuess;

resultMessage = 连接成功;

}

catch (EndpointNotFoundException e)

{

string mes = eMessage;

resultCommunState = CommStateFailed;

resultMessage = CommMessagesNoServer;

}

catch (TimeoutException e)

{

string mes = eMessage;

resultCommunState = CommStateTimeOut;

resultMessage = CommMessagesTimeOuteMessahe;

}

catch (Exception e)

{

string mes = eMessage;

resultCommunState = CommStateFailed;

resultMessage = CommMessagesNoServer;

}

return result;

}

/// <summary>

/// 断开与wcf Server链接

/// </summary>

public void DisConnectSvr()

{

string _sDisConSvrMsg = stringFormat({}{} sMacAddress DisConnService()Message);

ClientsClient(ContextConnectionId)DisConSvr(_sDisConSvrMsg);

DebugWrite(_sDisConSvrMsg);

}

/// <summary>

/// 客户端与服务器端断开连接

/// </summary>

/// <returns></returns>

private CommunResult DisConnService()

{

CommunResult result = new CommunResult();

try

{

ClientComServiceFactoryGetClientServiceFactoryGetClientComServiceDisConnect(sMacAddress);

resultCommunState = CommStateScuess;

resultMessage = 断开连接成功;

}

catch (EndpointNotFoundException e)

{

string mes = eMessage;

resultCommunState = CommStateFailed;

resultMessage = CommMessagesNoServer;

}

catch (TimeoutException e)

{

string mes = eMessage;

resultCommunState = CommStateTimeOut;

resultMessage = CommMessagesTimeOuteMessahe;

}

catch (Exception e)

{

string mes = eMessage;

resultCommunState = CommStateFailed;

resultMessage = CommMessagesNoServer;

}

return result;

}

/// <summary>

/// 心跳包保持与wcf server链接

/// </summary>

public void MonitorClientChanel()

{

if (stringIsNullOrEmpty(sUserPassword) || stringIsNullOrEmpty(sUserName))

return;

ThreadPoolQueueUserWorkItem

(

delegate

{

while (true)

{

ThreadSleep();

try

{

DebugWriteLine(stringFormat({}Client ID:{} ContextConnectionId DateTimeNow));

if (ClientComServiceFactoryGetClientServiceFactorygetObjetcStatusState == CommunicationStateFaulted)

{

ClientComServiceFactoryGetClientServiceFactorygetObjetcStatusAbort();

ClientComServiceFactoryGetClientServiceFactoryGetNewClientComService();

}

ClientComServiceFactoryGetClientServiceFactoryGetClientComServiceReConnect(sMacAddress sUserName sUserPassword);

}

catch (Exception ex)

{

ClientComServiceFactoryGetClientServiceFactoryGetNewClientComService();

DebugWriteLine(stringFormat(Time:{}Exception:{}Type:{} DateTimeNowToString(HH:mm:ss) exMessageToString() thisGetType()ToString()));

}

}

}

);

}

/// <summary>

/// 链接wcf Server

/// </summary>

/// <param name=clientMacAddress>Mac地址</param>

public void ConServer(string clientMacAddress)

{

//DebugerHelper dHelper = new DebugerHelper(DebugParameterObtainCalledMethod);

//dHelperFormartDebuger(Test);

CommunResult _comStatus = ConnService(clientMacAddress);

//FormartDebuger(MethodBaseGetCurrentMethod() hello);

ClientsClient(ContextConnectionId)CntServerResult(clientMacAddress _comStatusMessage);

if (_comStatusCommunState == CommStateScuess)

{

sMacAddress = clientMacAddress;

bIsConnect = true;

}

}

/// <summary>

/// 用户登录

/// </summary>

/// <param name=sName>用户名称</param>

/// <param name=sPassWord>用户密码</param>

public void UserLogin(string sName string sPassWord)

{

if (CheckConnectStatus())

{

LoginResult _serverLoginResult = ClientComServiceFactoryGetClientServiceFactoryGetClientComServiceUserLogin(sMacAddress sName sPassWord);

if (_serverLoginResultUserLoginStatus == LoginStatusscuess)

{

sUserName = sName;

sUserPassword = sPassWord;

ServiceCallBackRealTimeCabChCallBack += RealTimeCabChCallBackMessage_Event;

}

ClientsClient(ContextConnectionId)OperateMsg(stringFormat(用户:{}登录{} sName _serverLoginResultUserLoginStatus == LoginStatusscuess ? 成功 : 失败原因: + _serverLoginResultLoginMessage));

}

}

/// <summary>

/// 应急操作

/// </summary>

public void EmergencyControl()

{

if (CheckConnectStatus())

{

OptRealCtuChannelParameter parameter = new OptRealCtuChannelParameter();

parameterbyChActType = ;

parameterbyChActType = ;

parameterbyChActType = ;

parameterbyChActType = ;

parameterbyChActType = ;

parameterbyChActType = ;

parameterCabID = afabccbfbcfcfbfa;

parameterClientMacAddress = sMacAddress;

parameterOptTimeOut = ;

parameterOptRealDateTime = DateTimeNow;

parameterRealTimeStatus = ;

SvrRetMessage returnMessage = ClientComServiceFactoryGetClientServiceFactoryGetClientComServiceSendOptRealTimeCtuChMessage(parameter sMacAddress);

ClientsClient(ContextConnectionId)OperateMsg(stringFormat(CabID:{}应急控制操作:{} parameterCabID returnMessageExcuResult == true ? 成功 : 失败原因: + returnMessageMessage));

}

}

/// <summary>

/// 检查是否已经连接wcf Server

/// </summary>

/// <returns></returns>

private bool CheckConnectStatus()

{

if (bIsConnect && !stringIsNullOrEmpty(sMacAddress))

return true;

else

ClientsClient(ContextConnectionId)OperateMsg(当前还未连接CityLms Server);

return false;

}

}

}

实现效果

才疏学浅如有错误敬请指出

上一篇:C#操作Access数据库的例子

下一篇:给数据访问层添加参数化的方法