您的位置:首页 > 其它

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

2014-04-02 15:52 405 查看
原文:[SignalR]SignalR与WCF双工模式结合实现服务端数据直推浏览器端之前开发基于WinForm监控的软件,服务端基于Wcf实现,里面涉及双工模式,在客户端里面,采用心跳包机制保持与服务端链接,现在有了新需求,需要开发网页版形式,所以怎么保持与服务端链接是重要点,由于数据量比较大,所以不能采用客户端发起请求不断轮询的方式。参考各种资料后,使用SignalR,主要是支持WebSockets通信。并且Hub链接方式解决了realtime 信息交换的功能问题。下图是MSDN关于解释:Hub:提供与连接到 Hub 的 SignalR 连接进行通信的方法。Global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Web.Routing;
using Microsoft.AspNet.SignalR;
namespace LMSCitySignalR
{
public class Global : System.Web.HttpApplication
{

protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs();
}

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)
{

}
}
}
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt{background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }页面代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CityLmsClient.aspx.cs" Inherits="LMSCitySignalR.CityLmsClient" %>

<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>LH CityLMS Client</title>
</head>
<body>
<div id="dvMsg"></div>
Client Mac Address:
<input id="txtMac" type="text" value="50:E5:49:DA:4C:D6" />
<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/jquery-1.6.4.js" type="text/javascript"></script>
<script src="Scripts/json2.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR-1.1.1.js" type="text/javascript"></script>

<script src="/signalr/hubs" type="text/javascript"></script>
<script type="text/javascript">
$(function () {

/*
*  参考链接:http://www.cnblogs.com/shanyou/archive/2012/07/28/2613693.html
*· Persistent Connection(HTTP持久链接):持久性连接,用来解决长时间连接的能力,而且还可以由客户端主动向服务器要求数据,而服务器端也不需要实现太多细节,只需要处理 PersistentConnection 内所提供的五个事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
*· Hub:信息交换器,用来解决 realtime 信息交换的功能,服务器端可以利用 URL 来注册一个或多个 Hub,只要连接到这个 Hub,就能与所有的客户端共享发送到服务器上的信息,同时服务器端可以调用客户端的脚本,不过它背后还是不离 HTTP 的标准,所以它看起来神奇,但它并没有那么神奇,只是 JavaScript 更强,强到可以用像 eval() 或是动态解释执行的方式,允许 JavaScript 能够动态的加载与执行方法调用而己。
*/
/*链接对应server端Hub对象*/
var cityLmsClient = $.connection.cityLmsClientHub;
cityLmsClient.client.cntServerResult = function (name, message) {
$('#dvMsg').append('<li><strong>' + (new Date()).toLocaleTimeString() + '-Client Mac Address:' + name
+ ',   Connect CityLms Server Result:' + message + '</strong></li>');
};
/*断开连接消息提示*/
cityLmsClient.client.disConSvr = function (message) {
alert(message);
};
/*操作消息提示*/
cityLmsClient.client.operateMsg = function (message) {
$('#dvMsg').append('<li><strong>' + (new Date()).toLocaleTimeString() + '-' + message + '</strong></li>');
};

$.connection.hub.start().done(function () {

/*链接wcf Server*/
$("#btnCnLmsSvr").click(function () {
cityLmsClient.server.conServer($("#txtMac").val());
});

/*应急操作*/
$("#btnEmergencyControl").click(function () {
cityLmsClient.server.emergencyControl();
});
/*用户登录*/
$("#btnLogin").click(function () {
cityLmsClient.server.userLogin($("#txtUserName").val(), $("#txtUserPassword").val());
});
/*启动心跳包,以保持与wcf Server连接*/
$("#btnMonitorClientChanel").click(function () {
cityLmsClient.server.monitorClientChanel();
});
/*断开连接*/
$("#btnDisConSvr").click(function () {
cityLmsClient.server.disConnectSvr();
});
});
/*日志显示*/
$.connection.hub.logging = true;

});

</script>

</body>
</html>
cityLmsClientHub.cs代码.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt{background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }
using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Reflection;using System.ServiceModel;using System.Threading;using System.Web;using DL_LMS_Server.Default.Shared;using DL_LMS_Server.Service.DataModel.Parameter;using DL_LMS_Server.Service.DataModel.Result;using Microsoft.AspNet.SignalR;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 = e.NotifiedMessage as COptRealTimeCabChResult;string _sMsg = string.Format("{0}-CabID:{1},byCh1ActType:{2},byCh2ActType:{3},byCh3ActType:{4},byCh4ActType:{5},byCh5ActType:{5},byCh6ActType:{6},CtuLockStatus:{7}",DateTime.Now.ToShortTimeString(),optCabChresult.CabID,optCabChresult.byCh1ActType,optCabChresult.byCh2ActType,optCabChresult.byCh3ActType,optCabChresult.byCh4ActType,optCabChresult.byCh5ActType,optCabChresult.byCh6ActType,optCabChresult.CtuLockStatus);Clients.Client(Context.ConnectionId).OperateMsg(_sMsg);Clients.Client(Context.ConnectionId).OperateMsg("==========================end======================");}public void Hello(){Clients.All.hello();}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 = ClientComServiceFactory.GetClientServiceFactory.GetClientComService.Connect(clientMacAddress);if (!svrMessage.ExcuResult){result.Message = svrMessage.Message;result.CommunState = CommState.NoRegister;}result.CommunState = CommState.Scuess;result.Message = "连接成功";}catch (EndpointNotFoundException e){string mes = e.Message;result.CommunState = CommState.Failed;result.Message = CommMessage.sNoServer;}catch (TimeoutException e){string mes = e.Message;result.CommunState = CommState.TimeOut;result.Message = CommMessage.sTimeOuteMessahe;}catch (Exception e){string mes = e.Message;result.CommunState = CommState.Failed;result.Message = CommMessage.sNoServer;}return result;}/// <summary>/// 断开与wcf Server链接/// </summary>public void DisConnectSvr(){string _sDisConSvrMsg = string.Format("{0}{1}.", sMacAddress, DisConnService().Message);Clients.Client(Context.ConnectionId).DisConSvr(_sDisConSvrMsg);Debug.Write(_sDisConSvrMsg);}/// <summary>/// 客户端与服务器端断开连接/// </summary>/// <returns></returns>private CommunResult DisConnService(){CommunResult result = new CommunResult();try{ClientComServiceFactory.GetClientServiceFactory.GetClientComService.DisConnect(sMacAddress);result.CommunState = CommState.Scuess;result.Message = "断开连接成功";}catch (EndpointNotFoundException e){string mes = e.Message;result.CommunState = CommState.Failed;result.Message = CommMessage.sNoServer;}catch (TimeoutException e){string mes = e.Message;result.CommunState = CommState.TimeOut;result.Message = CommMessage.sTimeOuteMessahe;}catch (Exception e){string mes = e.Message;result.CommunState = CommState.Failed;result.Message = CommMessage.sNoServer;}return result;}/// <summary>/// 心跳包,保持与wcf server链接/// </summary>public void MonitorClientChanel(){if (string.IsNullOrEmpty(sUserPassword) || string.IsNullOrEmpty(sUserName))return;ThreadPool.QueueUserWorkItem(delegate{while (true){Thread.Sleep(5000);try{Debug.WriteLine(string.Format("{1}-Client ID:{0}", Context.ConnectionId, DateTime.Now));if (ClientComServiceFactory.GetClientServiceFactory.getObjetcStatus.State == CommunicationState.Faulted){ClientComServiceFactory.GetClientServiceFactory.getObjetcStatus.Abort();ClientComServiceFactory.GetClientServiceFactory.GetNewClientComService();}ClientComServiceFactory.GetClientServiceFactory.GetClientComService.ReConnect(sMacAddress, sUserName, sUserPassword);}catch (Exception ex){ClientComServiceFactory.GetClientServiceFactory.GetNewClientComService();Debug.WriteLine(string.Format("Time:{0}-Exception:{1}-Type:{2}", DateTime.Now.ToString("HH:mm:ss"), ex.Message.ToString(), this.GetType().ToString()));}}});}/// <summary>/// 链接wcf Server/// </summary>/// <param name="clientMacAddress">Mac地址</param>public void ConServer(string clientMacAddress){//DebugerHelper dHelper = new DebugerHelper(DebugParameter.ObtainCalledMethod);//dHelper.FormartDebuger("Test");CommunResult _comStatus = ConnService(clientMacAddress);//FormartDebuger(MethodBase.GetCurrentMethod(), "hello");Clients.Client(Context.ConnectionId).CntServerResult(clientMacAddress, _comStatus.Message);if (_comStatus.CommunState == CommState.Scuess){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 = ClientComServiceFactory.GetClientServiceFactory.GetClientComService.UserLogin(sMacAddress, sName, sPassWord);if (_serverLoginResult.UserLoginStatus == LoginStatus.scuess){sUserName = sName;sUserPassword = sPassWord;ServiceCallBack.RealTimeCabChCallBack += RealTimeCabChCallBackMessage_Event;}Clients.Client(Context.ConnectionId).OperateMsg(string.Format("用户:{0},登录:{1}。", sName, _serverLoginResult.UserLoginStatus == LoginStatus.scuess ? "成功" : "失败,原因:" + _serverLoginResult.LoginMessage));}}/// <summary>/// 应急操作/// </summary>public void EmergencyControl(){if (CheckConnectStatus()){OptRealCtuChannelParameter parameter = new OptRealCtuChannelParameter();parameter.byCh1ActType = 1;parameter.byCh2ActType = 1;parameter.byCh3ActType = 1;parameter.byCh4ActType = 1;parameter.byCh5ActType = 1;parameter.byCh6ActType = 1;parameter.CabID = "640afa41-b3c6-4c77-bf1b-cf2c4977fbfa";parameter.ClientMacAddress = sMacAddress;parameter.OptTimeOut = 10000;parameter.OptRealDateTime = DateTime.Now;parameter.RealTimeStatus = 63;SvrRetMessage returnMessage = ClientComServiceFactory.GetClientServiceFactory.GetClientComService.SendOptRealTimeCtuChMessage(parameter, sMacAddress);Clients.Client(Context.ConnectionId).OperateMsg(string.Format("CabID:{0},应急控制,操作:{1}。", parameter.CabID, returnMessage.ExcuResult == true ? "成功" : "失败,原因:" + returnMessage.Message));}}/// <summary>/// 检查是否已经连接wcf Server/// </summary>/// <returns></returns>private bool CheckConnectStatus(){if (bIsConnect && !string.IsNullOrEmpty(sMacAddress))return true;elseClients.Client(Context.ConnectionId).OperateMsg("当前还未连接CityLms Server.");return false;}}}
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt{background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }实现效果才疏学浅,如有错误,敬请指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐