用 Fleck 实现 websocket 通信
<html lang="en"> <head> <meta charset="utf-8"> <title>rfid</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1" name="viewport"> <meta content="" name="description"> <meta content="" name="author"> <link href="css/bootstrap.css" rel="stylesheet" type="text/css"> <link href="css/components-rounded.css" rel="stylesheet" id="style_components" type="text/css"> <link href="css/layout.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="echarts.min.js"></script> <script type="text/javascript" src="jquery-3.3.1.min.js"></script> <script type="text/javascript"> </script> </head> <body class="page-container-bg-solid page-boxed" style="overflow-x:hidden;"> <div class="page-container"> <div class="page-content-wrapper"> <div class="page-content"> <div class="container"> <div class="page-content-inner"> <div class="row" style="background-color:lightblue;"> <div class="caption font-blue-dark" style="font-size:16px;"> <span class="caption-subject bold uppercase" style="margin-left:5px;">综合概况</span> </div> </div> <div class="row" style="padding:5px;background-color:lightblue;"> <div class="col-md-6 col-sm-6" style="width:25%;"> <div class="portlet light "> <div class="portlet-title"> <div class="caption font_blue"> <span class="caption-md"></span> <span class="caption-desc">按部门(%)</span> </div> <div class="actions"> </div> </div> <div class="portlet-body"> <div id="dashboard_amchart_4" class="CSSAnimationChart"> <div class="amcharts-main-div"> <div class="amcharts-chart-div"> <div id="div1" onclick="sendMessage('10');" style="height:300px;margin-top:-20px;"></div> </div> </div> </div> </div> </div> </div> <div class="col-md-6 col-sm-6" style="width:25%;"> <div class="portlet light "> <div class="portlet-title"> <div class="caption font_blue"> <span class="caption-md"></span> <span class="caption-desc">按类别(%)</span> </div> <div class="actions"> </div> </div> <div class="portlet-body"> <div id="dashboard_amchart_4" class="CSSAnimationChart"> <div class="amcharts-main-div"> <div class="amcharts-chart-div"> <div id="div2" onclick="sendMessage('11');" style="height:300px;margin-top:-20px;"></div> </div> </div> </div> </div> </div> </div> </div> <div class="row" style="padding:5px;background-color:lightgray;"> <div class="row" style="margin-left:-15px;margin-right:-15px;"> <div class="portlet light" style="background-color:#556422;height:290px;margin-left:15px;margin-right:15px;"> <div class="col-md-6" style="width:400px;"> <table id="tableData" class="table table-bordered table-hover"> <thead> <tr style="background-color:#31753c;"> <td>楼层</td> <td> <img src="../监控数.png" /> <label>监控数</label> </td> <td> <img src="../丢失数.png" /> <label>缺失数</label> </td> </tr> </thead> <tbody> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> </tbody> </table> </div> <div style="float:right;"> <img id="imgbg" style="width:800px;height:290px;" src="../bgpart0.png" /> </div> </div> </div> </div> </div> </div> </div> </div> </div> <script type="text/javascript"> //echart params var echartDiv1 = echarts.init(document.getElementById('div1')); var echartDiv2 = echarts.init(document.getElementById('div2')); //websocket var ws = new WebSocket('ws://localhost:7181/'); //连接上服务端后触发 ws.onopen = function () { console.log('Connection to server opened'); } //收到服务端发来的消息后触发 ws.onmessage = function (evt) { var data = JSON.parse(evt.data); echartDiv1.setOption(data.chartOption1); echartDiv2.setOption(data.chartOption2); //位置实时统计数据 var realTimeMonitorData = data.realTimeMonitors; var len = realTimeMonitorData.length; for (var i = 0; i < len; i++) { var flooNo = realTimeMonitorData[i].FloorNo; var floorNo1 = flooNo + 400; var floorNo2 = flooNo + 500; var trStr = ""; trStr += "<td onclick=\"sendMessage('" + floorNo1 + "'); \"> " + flooNo + " </td>"; trStr += "<td onclick=\"sendMessage('" + floorNo2 + "1'); \">" + realTimeMonitorData[i].MonitorSum + "</td>"; trStr += "<td onclick=\"sendMessage('" + floorNo2 + "2'); \">" + realTimeMonitorData[i].LossSum + "</td>"; //注意:tr绑定的事件不能失效 $(".table-hover > tbody > tr").eq(i).html(trStr); } } //当服务端关闭后触发 ws.onclose = function () { console.log("Connection closed"); } //发送消息给服务器端 function sendMessage(msg) { if (ws.readyState == WebSocket.OPEN) { ws.send(msg); } } //断开与服务器端的连接 function disConnect() { ws.close(); } //page navigate $(".table-hover > tbody > tr").mouseover(function () { var idx = $(this).index(); $("#imgbg").attr("src", "../bgpart" + (10 - idx) + ".png"); }); $(".table-hover").mouseleave(function () { $("#imgbg").attr("src", "../bgpart0.png"); }); </script> </body> </html>
using DevExpress.XtraBars.Ribbon; using Fleck; using IMS.DBHelper; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Windows.Forms; using WHC.Framework.Commons; using RfidPositioning.Common; using IMS.BaseFramework; using System.Threading; namespace IMS.WfmClient { public partial class WebMonitor : RibbonForm { static System.Timers.Timer _refreshDataTimer = new System.Timers.Timer(); static List<IWebSocketConnection> _connections = new List<IWebSocketConnection>(); DataPackage _dataPackage = new DataPackage(); WebSocketServer _wsServer = new WebSocketServer("ws://0.0.0.0:7181"); public WebMonitor() { InitializeComponent(); //启动线程开始从数据库获取页面所需的数据 Thread th = new Thread(GetDataForChart); th.IsBackground = true; th.Start(); //设置监控界面对应的网页 string appPath = AppDomain.CurrentDomain.BaseDirectory; string chartsPath = "file:///" + appPath + "Resources/eCharts/sample.html"; webBrowser1.Navigate(new Uri(chartsPath)); //启动webSocket侦听服务 _wsServer.Start(item => { //与客户端建立连接后触发 item.OnOpen = () => { _connections.Add(item); //首次建立连接后立刻发送一次数据,之后由定时器来刷新数据 string jsonData = _dataPackage.ToJson(); _connections.ToList().ForEach(s => s.Send(jsonData)); }; //收到客户端发来的消息后触发 item.OnMessage = message => { int msg = 0; int.TryParse(message, out msg); ClientMessageHandler(msg); }; //客户端关闭连接后触发 item.OnClose = () => { _connections.Remove(item); }; }); } private void FrmIndex_Load(object sender, EventArgs e) { // 启动定时器 _refreshDataTimer.Enabled = true; _refreshDataTimer.Interval = 5 * 60 * 1000; _refreshDataTimer.Elapsed += new System.Timers.ElapsedEventHandler(timersTimer_Elapsed); _refreshDataTimer.Start(); } private void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { GetDataForChart(); string jsonData = _dataPackage.ToJson(); _connections.ToList().ForEach(s => s.Send(jsonData)); } private void ClientMessageHandler(int msg) { if (msg >= 500) { SysConfig.FloorNumber = (msg % 100).ToString(); this.Invoke(new Action(() => { ChildWinManagement.LoadMdiForm(SysConfig.mainform, typeof(frmTracePlayback)); })); } else if (msg >= 400) { SysConfig.FloorNumber = (msg / 10 % 100).ToString(); if (msg % 10 == 1) { SysConfig.WarningType = "正常"; } if (msg % 10 == 2) { SysConfig.WarningType = "缺失报警"; } this.Invoke(new Action(() => { ChildWinManagement.LoadMdiForm(SysConfig.mainform, typeof(AssetWatchDetail)); })); } else { StaticsTypeEnum type = (StaticsTypeEnum)msg; int typeScale = 0; int typeChecks = 0; int typePosition = 0; int typeInstrument = 0; getStaticsType(out typeScale, out typeChecks, out typePosition, out typeInstrument); switch (msg) { case 10: case 11: SysConfig.ReportByAssetsType = msg == 10 ? false : true; NavigateToForm(typePosition, typeof(FrmAssetsValueReport)); break; case 12: case 13: SysConfig.ReportByAssetsType = msg == 12 ? false : true; NavigateToForm(typePosition, typeof(FrmInventoryReport)); break; case 30: webBrowser1.Refresh(); break; case 31: this.Invoke(new Action(() => { Form form = new SetStaticsType(); form.Owner = this; form.StartPosition = FormStartPosition.CenterScreen; form.ShowDialog(); })); break; default: break; } } } private void getStaticsType(out int typeScale, out int typeChecks, out int typePosition, out int typeInstrument) { typeScale = 0; typeChecks = 0; typePosition = 0; typeInstrument = 0; //查询默认选择的统计方式(从数据库获取已设置过的数据) string strsql = "select * from HT_MonitorStaticsType;"; DataSet ds = SQLHelper.Query(SQLHelper._connstr, strsql); if (ds != null && ds.Tables != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { typeScale = Convert.ToInt32(ds.Tables[0].Rows[0]["Monitor"].ToString()); typeChecks = Convert.ToInt32(ds.Tables[0].Rows[0]["Checks"].ToString()); typePosition = Convert.ToInt32(ds.Tables[0].Rows[0]["Position"].ToString()); typeInstrument = Convert.ToInt32(ds.Tables[0].Rows[0]["Instrument"].ToString()); } } private void NavigateToForm(int type, Type formType) { if (type == 1) //按月 { SysConfig.ReportStartDate = DateTime.Now.ToString("yyyyMM") + "01"; SysConfig.ReportEndDate = DateTime.Now.AddMonths(1).ToString("yyyyMM") + "01"; } else { SysConfig.ReportStartDate = DateTime.Now.AddYears(-1).ToString("yyyyMMdd"); SysConfig.ReportEndDate = DateTime.Now.ToString("yyyyMMdd"); } this.Invoke(new Action(() => { ChildWinManagement.LoadMdiForm(SysConfig.mainform, formType); })); } #region 图表数据 class RealTimeMonitor { public string FloorNo { get; set; } public string MonitorSum { get; set; } public string LossSum { get; set; } public string PositionSum { get; set; } public string LowSum { get; set; } } class ChartAssetWatch { public string Name { get; set; } public string Value { get; set; } public string StaticsType { get; set; } } class ChartCheck { public string Name { get; set; } public string Value { get; set; } public string DataType { get; set; } public string StaticsType { get; set; } } class ChartPosition { public string Name { get; set; } public string Value { get; set; } public string DataType { get; set; } public string StaticsType { get; set; } } class ChartInstrument { public string Name { get; set; } public string Value { get; set; } public string StaticsType { get; set; } } class DataPackage { public ChartOptionForAssetWatch chartOption1 { get; set; } public ChartOptionForAssetWatch chartOption2 { get; set; } public ChartOption chartOption3 { get; set; } public ChartOption chartOption4 { get; set; }public List<RealTimeMonitor> realTimeMonitors { get; set; } } void GetDataForChart() { int typeScale = 0; int typeChecks = 0; int typePosition = 0; int typeInstrument = 0; getStaticsType(out typeScale, out typeChecks, out typePosition, out typeInstrument); _dataPackage.chartOption1 = getChartDataAssetWatch("HT_ChartAssetWatchDept", typeScale); _dataPackage.chartOption2 = getChartDataAssetWatch("HT_ChartAssetWatchType", typeScale); _dataPackage.chartOption3 = getChartDataCheck("HT_ChartCheckDept", typeChecks); _dataPackage.chartOption4 = getChartDataCheck("HT_ChartCheckType", typeChecks); List<RealTimeMonitor> realTimeMonitors = getRealTimeMonitorData(); _dataPackage.realTimeMonitors = realTimeMonitors; } ChartOptionForAssetWatch getChartDataAssetWatch(string tableName, int staticsType) { ChartOptionForAssetWatch chartOption = new ChartOptionForAssetWatch(); try { string sqlStr = @"SELECT [Name],[Value],[StaticsType] FROM XXX.[dbo].[" + tableName + "] WHERE StaticsType = " + staticsType + " order by Name desc;"; DataSet ds = SQLHelper.Query(SQLHelper._connstr, sqlStr); List<ChartAssetWatch> chartData = ds.Tables[0].ConvertToModel<ChartAssetWatch>(); //截取长度超出5的字符串 chartData.ForEach(item => { if (item.Name.Length > 5) { item.Name = item.Name.Substring(0, 4) + ".."; } }); //合并数量少的分组 List<ChartAssetWatch> chartDataNew = new List<ChartAssetWatch>(); chartDataNew.AddRange(chartData.OrderByDescending(p => p.Value).Take(5)); //取前5条数据 chartDataNew.ForEach(p => { chartData.Remove(p); }); chartDataNew.Add(new ChartAssetWatch { Name = "其他", Value = chartData.Sum(p => Convert.ToDecimal(p.Value)).ToString() }); chartOption.tooltip = new tooltip(); chartOption.tooltip.trigger = "item"; chartOption.tooltip.formatter = "{a} <br/>{b}: {c} ({d}%)"; chartOption.legend = new legend(); chartOption.legend.type = "scroll"; chartOption.legend.orient = "vertical"; chartOption.legend.left = "0"; chartOption.legend.top = "0"; chartOption.legend.data = chartDataNew.Select(p => p.Name).ToArray(); chartOption.series = new SeriesForAssetWatch[1]; SeriesForAssetWatch series = new SeriesForAssetWatch(); series.name = ""; series.type = "pie"; series.radius = new string[] { "60%", "30%" }; series.center = new string[] { "55%", "55%" }; series.avoidLabelOverlap = "false"; series.label = new label(); series.label.normal = new normal(); series.label.normal.show = false; series.label.normal.position = "center"; series.label.emphasis = new emphasis(); series.label.emphasis.show = "true"; series.label.emphasis.textStyle = new textStyle(); series.label.emphasis.textStyle.fontSize = "20"; series.labelLine = new labelLine(); series.labelLine.normal = new normal(); series.labelLine.normal.show = false; List<DataNew> d = new List<DataNew>(); chartDataNew.ForEach(p => { d.Add(new DataNew { name = p.Name, value = p.Value }); }); series.data = d.ToArray(); chartOption.series = new SeriesForAssetWatch[1]; chartOption.series[0] = series; return chartOption; } catch { return null; } } ChartOption getChartDataCheck(string tableName, int staticsType) { ChartOption chartOption = new ChartOption(); try { string sqlStr = @"SELECT [Name],[Value],[DataType],[StaticsType] FROM [Lonix_Fas_1].[dbo].[" + tableName + "] WHERE StaticsType = " + staticsType + " order by Name desc;"; DataSet ds = SQLHelper.Query(SQLHelper._connstr, sqlStr); List<ChartCheck> chartData = ds.Tables[0].ConvertToModel<ChartCheck>(); //截取长度超出5的字符串 chartData.ForEach(item => { if (item.Name.Length > 5) { item.Name = item.Name.Substring(0, 4) + ".."; } }); //合并数量少的分组 List<ChartCheck> chartInstrumentsNew1 = new List<ChartCheck>(); chartInstrumentsNew1.AddRange(chartData.Where(p => p.DataType == "1").OrderByDescending(p => p.Value).Take(5)); //取前5条数据 chartInstrumentsNew1.ForEach(p => { chartData.Remove(p); }); chartInstrumentsNew1.Add(new ChartCheck { Name = "其他", Value = chartData.Where(p => p.DataType == "1").Sum(p => Convert.ToDecimal(p.Value)).ToString() }); List<ChartCheck> chartInstrumentsNew2 = new List<ChartCheck>(); chartInstrumentsNew2.AddRange(chartData.Where(p => p.DataType == "2").OrderByDescending(p => p.Value).Take(5)); //取前5条数据 chartInstrumentsNew2.ForEach(p => { chartData.Remove(p); }); chartInstrumentsNew2.Add(new ChartCheck { Name = "其他", Value = chartData.Where(p => p.DataType == "2").Sum(p => Convert.ToDecimal(p.Value)).ToString() }); chartOption.tooltip = new tooltip(); chartOption.tooltip.trigger = "axis"; chartOption.tooltip.axisPointer = new axisPointer(); chartOption.tooltip.axisPointer.type = "shadow"; chartOption.legend = new legend(); chartOption.legend.orient = "horizontal"; chartOption.legend.data = new string[] { "盘亏数", "已盘数" }; chartOption.grid = new grid(); chartOption.grid.top = "80"; chartOption.grid.left = "3%"; chartOption.grid.right = "6%"; chartOption.grid.bottom = "30"; chartOption.grid.containLabel = true; chartOption.xAxis = new Axis(); chartOption.xAxis.type = "value"; chartOption.xAxis.axisLabel = new axisLabel(); chartOption.xAxis.axisLabel.interval = "0"; chartOption.xAxis.axisLabel.rotate = "0"; chartOption.yAxis = new Axis(); chartOption.yAxis.type = "category"; chartOption.yAxis.data = chartInstrumentsNew1.Select(p => p.Name).ToArray(); chartOption.yAxis.axisLabel = new axisLabel(); chartOption.yAxis.axisLabel.interval = "0"; chartOption.yAxis.axisLabel.rotate = "0"; chartOption.series = new Series[2]; Series s1 = new Series(); s1.name = "盘亏数"; s1.type = "bar"; s1.stack = "总量"; s1.label = new label(); s1.label.normal = new normal(); s1.label.normal.show = true; s1.label.normal.position = "insideRight"; s1.data = chartInstrumentsNew1.Select(p => p.Value).ToArray(); chartOption.series[0] = s1; Series s2 = new Series(); s2.name = "已盘数"; s2.type = "bar"; s2.stack = "总量"; s2.label = new label(); s2.label.normal = new normal(); s2.label.normal.show = true; s2.label.normal.position = "insideRight"; s2.data = chartInstrumentsNew2.Select(p => p.Value).ToArray(); chartOption.series[1] = s2; return chartOption; } catch { return null; } } List<RealTimeMonitor> getRealTimeMonitorData() { string sqlStr = @"select [FloorNo],[MonitorSum],[LossSum],[PositionSum],[LowSum] from XXX.[dbo].[HT_RealTimeMonitor] order by FloorNo desc;"; DataSet ds = SQLHelper.Query(SQLHelper._connstr, sqlStr); return ds.Tables[0].ConvertToModel<RealTimeMonitor>(); } #endregion } }
namespace IMS.WfmClient { public class ChartOption { public tooltip tooltip { get; set; } public legend legend { get; set; } public grid grid { get; set; } public Axis xAxis { get; set; } public Axis yAxis { get; set; } public Series[] series { get; set; } } public class ChartOptionForAssetWatch { public tooltip tooltip { get; set; } public legend legend { get; set; } public grid grid { get; set; } public Axis xAxis { get; set; } public Axis yAxis { get; set; } public SeriesForAssetWatch[] series { get; set; } } public class tooltip { public string trigger { get; set; } public string formatter { get; set; } public axisPointer axisPointer { get; set; } } public class axisPointer { public string type { get; set; } } public class legend { public string type { get; set; } public string orient { get; set; } public string left { get; set; } public string top { get; set; } public string[] data { get; set; } } public class grid { public string top { get; set; } public string left { get; set; } public string right { get; set; } public string bottom { get; set; } public bool containLabel { get; set; } } public class Axis { public string type { get; set; } public axisLabel axisLabel { get; set; } public string[] data { get; set; } } public class axisLabel { public string interval { get; set; } public string rotate { get; set; } } public class Series { public string name { get; set; } public string type { get; set; } public string center { get; set; } public string avoidLabelOverlap { get; set; } public string stack { get; set; } public label label { get; set; } public string[] data { get; set; } } public class SeriesForAssetWatch { public string name { get; set; } public string type { get; set; } public string[] radius { get; set; } public string[] center { get; set; } public string avoidLabelOverlap { get; set; } public string stack { get; set; } public label label { get; set; } public labelLine labelLine { get; set; } public DataNew[] data { get; set; } } public class DataNew { public string value { get; set; } public string name { get; set; } } public class label { public normal normal { get; set; } public emphasis emphasis { get; set; } } public class normal { public bool show { get; set; } public string position { get; set; } } public class emphasis { public string show { get; set; } public textStyle textStyle { get; set; } } public class textStyle { public string fontSize { get; set; } } public class labelLine { public normal normal { get; set; } } }
posted on 2019-02-13 16:35 wangzhiliang 阅读(3150) 评论(0) 编辑 收藏 举报