- 浏览: 96880 次
- 性别:
- 来自: 深圳
-
文章分类
最新评论
-
grhglj:
能详细一点吗?都加到哪儿呀。
struts2.0中使用图形验证码 -
shingo7:
jotm哪来的2.3版
Spring引用Tomcat的 JTA事务 -
blogaaa:
这样配置完后,事务不能正常回滚,在同一个action中插入记录 ...
Spring引用Tomcat的 JTA事务
原文地址: http://www.micmiu.com/enterprise-app/snmp/snmp-jrobin-core-demo/
最近接触一个流量统计和网管的系统,对相关信息和技术做了一些了解和学习,在此记录,以供自己日后回顾,同时也方便给刚接触的TX们一些参考。
MRTG(Multi Router Traffic Grapher,MRTG),相信接触过网络管理的人,应该不会对它陌生的。MRTG是比较早的技术了,后来在此基础上发展了RRD技术,相比MRTG而言更加灵活方便。
JRobin(基于LGPL授权的开源技术)就是RRD的一个Java实现的版本。JRobin支持在RRD(Round Robin Database)上的所有标准操作:CREATE, UPDATE, FETCH, LAST, DUMP, XPORT和GRAPH。JRobin的API适合于那些熟悉RRDTool的概念与逻辑,但更喜欢使用纯Java实现的人。如果你提供相同的数据给RRDTool与JRobin,你将会得到相同的结果与图形。
ps:JRobin的官网:
http://oldwww.jrobin.org/
http://www.jrobin.org/index.php/Main_Page
先从Core API 开始了解学习如何定义RRD模板、如何创建RRD文件、如何获取RrdDb、如何将RRD文件和XML之间转换以及如何从RRD文件里读取数据等基础内容,下面是学习时写的一些测试代码:TestCoreRrd.java
1 |
package com.snmp.jrobin;
|
2 |
3 |
import org.jrobin.core.DsDef;
|
4 |
import org.jrobin.core.DsTypes;
|
5 |
import org.jrobin.core.FetchData;
|
6 |
import org.jrobin.core.FetchRequest;
|
7 |
import org.jrobin.core.RrdDb;
|
8 |
import org.jrobin.core.RrdDef;
|
9 |
import org.jrobin.core.Sample;
|
10 |
import org.jrobin.core.Util;
|
11 |
12 |
/** |
13 |
* JRobin Core学习
|
14 |
* @author Michael sun
|
15 |
*/
|
16 |
public class TestCoreRrd {
|
17 |
/**
|
18 |
* @param args
|
19 |
*/
|
20 |
public static void main(String[] args) {
|
21 |
// 2010-10-01:1285862400L 2010-11-01:1288540800L
|
22 |
long startTime = Util.getTimestamp( 2010 , 10 - 1 , 1 );
|
23 |
long endTime = Util.getTimestamp( 2010 , 11 - 1 , 1 );
|
24 |
25 |
TestCoreRrd test = new TestCoreRrd();
|
26 |
String rootPath = "d:/test/jrobin/" ;
|
27 |
String rrdName = "demo_flow.rrd" ;
|
28 |
// 测试创建RrdDef
|
29 |
RrdDef rrdDef = test.createRrdDef(rootPath, rrdName, startTime);
|
30 |
// 测试创建RRD文件 初始数据
|
31 |
test.createRRDInitData(startTime, endTime, rootPath, rrdName, rrdDef);
|
32 |
// 测试获取RrdDb的方法
|
33 |
test.getRrdDbMethod(rootPath);
|
34 |
// 测试FetchData获取RRD
|
35 |
test.fetchRrdData(rootPath, rrdName);
|
36 |
}
|
37 |
38 |
/**
|
39 |
* 创建RRDDef
|
40 |
*/
|
41 |
private RrdDef createRrdDef(String rootPath, String rrdName, long startTime) {
|
42 |
try {
|
43 |
44 |
String rrdPath = rootPath + rrdName;
|
45 |
RrdDef rrdDef = new RrdDef(rrdPath, startTime - 1 , 300 );
|
46 |
// DsTypes: GAUGE COUNTER DERIVE ABSOLUTE
|
47 |
DsDef dsDef = new DsDef( "input" , DsTypes.DT_COUNTER, 600 , 0 ,
|
48 |
Double.NaN);
|
49 |
rrdDef.addDatasource(dsDef);
|
50 |
51 |
rrdDef.addDatasource( "output" , DsTypes.DT_COUNTER, 600 , 0 ,
|
52 |
Double.NaN);
|
53 |
54 |
rrdDef.addArchive( "AVERAGE" , 0.5 , 1 , 600 );
|
55 |
rrdDef.addArchive( "AVERAGE" , 0.5 , 6 , 700 );
|
56 |
rrdDef.addArchive( "AVERAGE" , 0.5 , 24 , 797 );
|
57 |
rrdDef.addArchive( "AVERAGE" , 0.5 , 288 , 775 );
|
58 |
rrdDef.addArchive( "MAX" , 0.5 , 1 , 600 );
|
59 |
rrdDef.addArchive( "MAX" , 0.5 , 6 , 700 );
|
60 |
rrdDef.addArchive( "MAX" , 0.5 , 24 , 797 );
|
61 |
rrdDef.addArchive( "MAX" , 0.5 , 288 , 775 );
|
62 |
63 |
// RRD file definition is completed
|
64 |
65 |
rrdDef.exportXmlTemplate(rootPath + rrdName + "_template.xml" );
|
66 |
System.out.println( "[RrdDef Template export xml success]" );
|
67 |
68 |
return rrdDef;
|
69 |
} catch (Exception e) {
|
70 |
e.printStackTrace();
|
71 |
return null ;
|
72 |
}
|
73 |
}
|
74 |
75 |
/**
|
76 |
* 通过RrdDef创建RRD文件并初始化数据
|
77 |
*/
|
78 |
private void createRRDInitData( long startTime, long endTime,
|
79 |
String rootPath, String rrdName, RrdDef rrdDef) {
|
80 |
try {
|
81 |
82 |
RrdDb rrdDb = new RrdDb(rrdDef);
|
83 |
// / by this point, rrd file can be found on your disk
|
84 |
85 |
// 模拟一些测试数据
|
86 |
//Math.sin(2 * Math.PI * (t / 86400.0)) * baseval;
|
87 |
int baseval = 50 ;
|
88 |
for ( long t = startTime; t < endTime; t += 300 ) {
|
89 |
Sample sample = rrdDb.createSample(t);
|
90 |
double tmpval = Math.random() * baseval;
|
91 |
double tmpval2 = Math.random() * baseval;
|
92 |
sample.setValue( "input" , tmpval + 50 );
|
93 |
sample.setValue( "output" , tmpval2 + 50 );
|
94 |
sample.update();
|
95 |
}
|
96 |
System.out.println( "[RrdDb init data success]" );
|
97 |
System.out.println( "[Rrd path]:" + rrdDef.getPath());
|
98 |
99 |
// rrdDb.dumpXml(rootPath + rrdName + "_rrd.xml")
|
100 |
rrdDb.exportXml(rootPath + rrdName + ".xml" );
|
101 |
102 |
// If your RRD files are updated rarely, open them only when
|
103 |
// necessary and close them as soon as possible.
|
104 |
rrdDb.close();
|
105 |
106 |
System.out.println( "[RrdDb export xml success]" );
|
107 |
} catch (Exception e) {
|
108 |
e.printStackTrace();
|
109 |
110 |
}
|
111 |
}
|
112 |
113 |
/**
|
114 |
* 除根据RrdDef以外获取RrdDb的其他方法
|
115 |
*/
|
116 |
private void getRrdDbMethod(String rootPath) {
|
117 |
try {
|
118 |
119 |
// 根据RRD文件获取RrdDb
|
120 |
String rrdFullPath = rootPath + "demo_flow.rrd" ;
|
121 |
RrdDb rrdDb = new RrdDb(rrdFullPath);
|
122 |
System.out.println( "[info:]" + rrdDb.getInfo() + "[path:]"
|
123 |
+ rrdDb.getPath());
|
124 |
rrdDb.close();
|
125 |
126 |
// 根据XML文件获取RrdDb
|
127 |
rrdDb = new RrdDb(rootPath + "copy.rrd" , rootPath
|
128 |
+ "demo_flow_rrd.xml" );
|
129 |
System.out.println( "[info:]" + rrdDb.getInfo() + "[path:]"
|
130 |
+ rrdDb.getPath());
|
131 |
rrdDb.close();
|
132 |
} catch (Exception e) {
|
133 |
e.printStackTrace();
|
134 |
}
|
135 |
}
|
136 |
137 |
/**
|
138 |
*
|
139 |
*/
|
140 |
private void fetchRrdData(String rootPath, String rrdName) {
|
141 |
try {
|
142 |
// open the file
|
143 |
RrdDb rrd = new RrdDb(rootPath + rrdName);
|
144 |
145 |
// create fetch request using the database reference
|
146 |
FetchRequest request = rrd.createFetchRequest( "AVERAGE" , Util
|
147 |
.getTimestamp( 2010 , 10 - 1 , 1 ), Util.getTimestamp( 2010 ,
|
148 |
10 - 1 , 2 ));
|
149 |
150 |
System.out.println( "[requet dump:]" + request.dump());
|
151 |
152 |
// filter the datasources you really need
|
153 |
// String[] filterDataSource = { "input", "output" };
|
154 |
// request.setFilter(filterDataSource);
|
155 |
156 |
// if you want only the "input" datasource use:
|
157 |
// request.setFilter("input");
|
158 |
159 |
// execute the request
|
160 |
FetchData fetchData = request.fetchData();
|
161 |
int columnCount = fetchData.getColumnCount();
|
162 |
int rowCount = fetchData.getRowCount();
|
163 |
long [] timestamps = fetchData.getTimestamps();
|
164 |
System.out.println( "[data column count:]" + columnCount);
|
165 |
System.out.println( "[data row count:]" + rowCount);
|
166 |
167 |
// System.out.println("[fetch data dump:]" + fetchData.dump());
|
168 |
// 循环获取数据
|
169 |
double [][] values = fetchData.getValues();
|
170 |
StringBuffer buffer = new StringBuffer( "" );
|
171 |
for ( int row = 0 ; row < rowCount; row++) {
|
172 |
buffer.append(timestamps[row]);
|
173 |
buffer.append( ": " );
|
174 |
for ( int dsIndex = 0 ; dsIndex < columnCount; dsIndex++) {
|
175 |
buffer.append(Util.formatDouble(values[dsIndex][row]));
|
176 |
buffer.append( " " );
|
177 |
}
|
178 |
buffer.append( "\n" );
|
179 |
}
|
180 |
System.out.println( "[fetch data display :]\n" + buffer);
|
181 |
} catch (Exception e) {
|
182 |
e.printStackTrace();
|
183 |
}
|
184 |
185 |
}
|
186 |
} |
RRD定义的模板导出XML:
1 |
< rrd_def >
|
2 |
< path >d:/test/jrobin/demo_flow.rrd</ path >
|
3 |
< step >300</ step >
|
4 |
< start >1285862399</ start >
|
5 |
< datasource >
|
6 |
< name >input</ name >
|
7 |
< type >COUNTER</ type >
|
8 |
< heartbeat >600</ heartbeat >
|
9 |
< min >+0.0000000000E00</ min >
|
10 |
< max >U</ max >
|
11 |
</ datasource >
|
12 |
< datasource >
|
13 |
< name >output</ name >
|
14 |
< type >COUNTER</ type >
|
15 |
< heartbeat >600</ heartbeat >
|
16 |
< min >+0.0000000000E00</ min >
|
17 |
< max >U</ max >
|
18 |
</ datasource >
|
19 |
< archive >
|
20 |
< cf >AVERAGE</ cf >
|
21 |
< xff >+5.0000000000E-01</ xff >
|
22 |
< steps >1</ steps >
|
23 |
< rows >600</ rows >
|
24 |
</ archive >
|
25 |
< archive >
|
26 |
< cf >AVERAGE</ cf >
|
27 |
< xff >+5.0000000000E-01</ xff >
|
28 |
< steps >6</ steps >
|
29 |
< rows >700</ rows >
|
30 |
</ archive >
|
31 |
< archive >
|
32 |
< cf >AVERAGE</ cf >
|
33 |
< xff >+5.0000000000E-01</ xff >
|
34 |
< steps >24</ steps >
|
35 |
< rows >797</ rows >
|
36 |
</ archive >
|
37 |
< archive >
|
38 |
< cf >AVERAGE</ cf >
|
39 |
< xff >+5.0000000000E-01</ xff >
|
40 |
< steps >288</ steps >
|
41 |
< rows >775</ rows >
|
42 |
</ archive >
|
43 |
< archive >
|
44 |
< cf >MAX</ cf >
|
45 |
< xff >+5.0000000000E-01</ xff >
|
46 |
< steps >1</ steps >
|
47 |
< rows >600</ rows >
|
48 |
</ archive >
|
49 |
< archive >
|
50 |
< cf >MAX</ cf >
|
51 |
< xff >+5.0000000000E-01</ xff >
|
52 |
< steps >6</ steps >
|
53 |
< rows >700</ rows >
|
54 |
</ archive >
|
55 |
< archive >
|
56 |
< cf >MAX</ cf >
|
57 |
< xff >+5.0000000000E-01</ xff >
|
58 |
< steps >24</ steps >
|
59 |
< rows >797</ rows >
|
60 |
</ archive >
|
61 |
< archive >
|
62 |
< cf >MAX</ cf >
|
63 |
< xff >+5.0000000000E-01</ xff >
|
64 |
< steps >288</ steps >
|
65 |
< rows >775</ rows >
|
66 |
</ archive >
|
67 |
</ rrd_def >
|
RRD文件转换成XML文件的片段:
1 |
< rrd >
|
2 |
<!-- JRobin, version 0.1 -->
|
3 |
< version >0001</ version >
|
4 |
<!-- Seconds -->
|
5 |
< step >300</ step >
|
6 |
<!-- Sun Oct 31 23:55:00 CST 2010 -->
|
7 |
< lastupdate >1288540500</ lastupdate >
|
8 |
< ds >
|
9 |
< name >input</ name >
|
10 |
< type >COUNTER</ type >
|
11 |
< minimal_heartbeat >600</ minimal_heartbeat >
|
12 |
< min >+0.0000000000E00</ min >
|
13 |
< max >NaN</ max >
|
14 |
<!-- PDP Status -->
|
15 |
< last_ds >+6.9973544356E01</ last_ds >
|
16 |
< value >+0.0000000000E00</ value >
|
17 |
< unknown_sec >0</ unknown_sec >
|
18 |
</ ds >
|
19 |
< ds >
|
20 |
< name >output</ name >
|
21 |
< type >COUNTER</ type >
|
22 |
< minimal_heartbeat >600</ minimal_heartbeat >
|
23 |
< min >+0.0000000000E00</ min >
|
24 |
< max >NaN</ max >
|
25 |
<!-- PDP Status -->
|
26 |
< last_ds >+9.4423065918E01</ last_ds >
|
27 |
< value >+0.0000000000E00</ value >
|
28 |
< unknown_sec >0</ unknown_sec >
|
29 |
</ ds >
|
30 |
< rra >
|
31 |
< cf >AVERAGE</ cf >
|
32 |
<!-- 300 seconds -->
|
33 |
< pdp_per_row >1</ pdp_per_row >
|
34 |
< xff >+5.0000000000E-01</ xff >
|
35 |
< cdp_prep >
|
36 |
< ds >
|
37 |
< value >NaN</ value >
|
38 |
< unknown_datapoints >0</ unknown_datapoints >
|
39 |
</ ds >
|
40 |
< ds >
|
41 |
< value >NaN</ value >
|
42 |
< unknown_datapoints >0</ unknown_datapoints >
|
43 |
</ ds >
|
44 |
</ cdp_prep >
|
45 |
< database >
|
46 |
<!-- Fri Oct 29 22:00:00 CST 2010 / 1288360800 -->
|
47 |
< row >
|
48 |
< v >+1.4316557626E07</ v >
|
49 |
< v >+1.2619069495E-01</ v >
|
50 |
</ row >
|
51 |
<!-- Fri Oct 29 22:05:00 CST 2010 / 1288361100 -->
|
52 |
< row >
|
53 |
< v >+1.4063324411E-02</ v >
|
54 |
< v >+1.4316557534E07</ v >
|
55 |
</ row >
|
56 |
<!-- 省略部分信息-->
|
57 |
...........................
|
58 |
</ database >
|
59 |
</ rra >
|
60 |
<!-- 省略部分信息-->
|
61 |
...............................
|
62 |
</ rrd >
|
发表评论
-
Drools与Spring集成 登录测试
2013-07-12 15:27 0转至: http://justsee.iteye.com/b ... -
Drools入门-----------环境搭建,分析Helloworld
2013-07-12 15:20 0转至: http://justsee.iteye.com/b ... -
H2学习
2013-07-12 15:11 0package test.h2; import ja ... -
BlockingQueue队列学习
2013-10-17 10:16 839package test; import java ... -
一个多线程计算器的实现
2013-07-12 14:56 0package test; import java.util ... -
Memcached学习——(四)
2012-11-28 17:11 0原文地址: http://snowolf.iteye.com/ ... -
Memcached学习——(三)
2012-11-28 17:10 0原文地址: http://snowolf ... -
Memcached学习——(二)
2012-11-28 17:08 1025原文地址: http://snowolf.iteye.com/ ... -
Memcached学习——(一)
2012-11-28 17:07 1184原文地址: http://snowolf.iteye.com/ ... -
redis学习
2012-11-28 17:03 989原文地址:http://snowolf.iteye.com/b ... -
基于Spring可扩展Schema提供自定义配置支持(spring配置文件中 配置标签支持)
2012-11-28 16:55 846原文地址:http://www.cnblogs.com/jif ... -
JAI处理TIFF格式图片
2012-09-17 17:48 13355懒得多说,直接代码了。。。。 import java.awt. ... -
全面掌握Java的异常处理机制
2009-03-05 17:17 1074你觉得自己是一个Java专 ... -
java.lang包概述
2009-03-05 17:02 133954.1. 接口 java.lang.Appendab ... -
select下拉列表动态显示选择公司及部门信息——级联
2008-11-25 12:29 1348//=================公司类方法======= ... -
人民币大小写转
2008-11-25 12:26 1183String HanDigiStr[] = new Strin ... -
身份证号转换15位与18位
2008-11-25 12:24 1642//开始 15位到18位的身份证号转换 //身份证号码由 ... -
使ApplicationResources.properties支持中文
2008-11-25 12:15 1355使ApplicationResources.propertie ... -
利用XMLBean轻轻松松读写XML
2008-11-25 12:11 991一、关于XML解析 XML在Java应用程序里变得越来越 ... -
JAVA获得网卡MAC地址
2008-11-25 12:06 1185package test; import java.io.B ...
相关推荐
Jrobin、SNMP4jsnmp4j-1x-demoSNMP4j实现同步和异步的GET的示例SNMP4j实现同步和异步的Walk的示例SNMP4j实现Trap的示例SNMP4j实现SET的示例SNMP4j实现GETBLUK的示例robin-demoJRobin Core学习JRobin基础画图JRobin...
hhhhh安卓开发教程大全
avem-labs_Avem_1740990015.zip
微信群机器人管理系统源码 微信群机器人管理系统源码 支持同登陆多个微信 源码类型: C/S 开发环境: VS2010 SQL2008R2 菜单功能 1、支持同时登录多个微信 2、支持机器人聊天(笑话,成语接龙、故事会、智力等等) 3、支持签到 4、可自定义回复 5、可自定义红包语 6、支持定期发送公告(如群规,广告)等 1、WeChatRobots后台配置web版 2、数据库在WeiChartGroup.Net/app_data中,附加即可
https://upload.csdn.net/creation/uploadResources?spm=1003.2018.3001.4314
名字微控制器_STM32_课程_DeepBlue_1740989720.zip
S7-200Smart恒压供水程序示例与485通讯实践:操作指南与案例解析,S7-200 Smart可编程控制器恒压供水程序设计与实现,附带485通讯范例,S7-200Smart 恒压供水程序样例+485通讯样例 ,S7-200Smart; 恒压供水程序样例; 485通讯样例,S7-200Smart程序样例:恒压供水及485通讯应用示例
Java使用JNA、JNI两种不同方式调用DLL、SO动态库方式读写M1卡源码,支持读写M1卡扇区数据、修改IC卡扇区密钥、改写UID卡卡号等功能,支持Windows系统,同时支持龙芯Mips、LoongArch、海思麒麟鲲鹏飞腾Arm、海光兆芯x86_Amd64等架构平台的国产统信、麒麟等Linux系统,内有jna-4.5.0.jar包,vx13822155058 qq954486673
UDP协议接收和发送数据示例JAVA
本文介绍了范德堡大学深脑刺激器(DBS)项目,该项目旨在开发和临床评估一个系统,以辅助从规划到编程的整个过程。DBS是一种高频刺激治疗,用于治疗运动障碍,如帕金森病。由于目标区域在现有成像技术中可见性差,因此DBS电极的植入和编程过程复杂且耗时。项目涉及使用计算机辅助手术技术,以及一个定制的微定位平台(StarFix),该平台允许在术前进行图像采集和目标规划,提高了手术的精确性和效率。此外,文章还讨论了系统架构和各个模块的功能,以及如何通过中央数据库和网络接口实现信息共享。
图像识别”项目源码资源(Python和C++)
虚拟同步电机与并电网模型的Simulink仿真参数配置与直接使用指南,虚拟同步电机与并电网模型的Simulink仿真:参数齐全,直接使用,同步电机simulink仿真 并电网模型仿真 参数设置好了,可直接使用 ,虚拟同步电机; simulink仿真; 并电网模型仿真; 参数设置; 使用,虚拟同步电机Simulink仿真与并电网模型参数化应用
三菱FX3U与力士乐VFC-x610变频器通讯案例详解:PLC控制下的变频器操作与设置程序,含接线方式及昆仑通态触摸屏操作指南,三菱FX3U与力士乐VFC-x610变频器通讯案例详解:接线、设置与程序注解,实现频率设定、启停控制与实时数据读取功能。,三菱FX3U与力士乐VFC-x610变频器通讯程序三菱FX3U与力士乐VFC-x610变频器通讯案例程序,有注释。 并附送程序,有接线方式,设置。 器件:三菱FX3U的PLC,力士乐VFCx610变频器,昆仑通态,威纶通触摸屏。 功能:实现频率设定,启停控制,实际频率读取等。 ,三菱FX3U;力士乐VFC-x610变频器;通讯程序;案例程序;注释;接线方式;设置;频率设定;启停控制;实际频率读取;昆仑通态;威纶通触摸屏。,三菱FX3U与力士乐VFC-x610变频器通讯程序及案例:频率控制与读取实践
xmselect测试用例~~~~~~~~~~~~~~
总共包含 32 款 AAA 级科幻武器。四种武器类型,每种有 8 种不同的纹理变化! 所有内容均采用 PBR 材质,可直接用于开发游戏!
python词云生成器,将txt文本自动分割生成词云图
智慧园区,作为现代城市发展的新形态,旨在通过高度集成的信息化系统,实现园区的智能化管理与服务。该方案提出,利用智能手环、定制APP、园区管理系统及物联网技术,将园区的各类设施与设备紧密相连,形成一个高效、便捷、安全的智能网络。从智慧社区到智慧酒店,从智慧景区到智慧康养,再到智慧生态,五大应用板块覆盖了园区的每一个角落,为居民、游客及工作人员提供了全方位、个性化的服务体验。例如,智能手环不仅能实现定位、支付、求助等功能,还能监测用户健康状况,让科技真正服务于生活。而智慧景区的建设,更是通过大数据分析、智能票务、电子围栏等先进技术,提升了游客的游玩体验,确保了景区的安全有序。 尤为值得一提的是,方案中的智慧康养服务,展现了科技对人文关怀的深刻体现。通过智慧手环与传感器,自动感知老人身体状态,及时通知家属或医疗机构,有效解决了“空巢老人”的照护难题。同时,智慧生态管理系统的应用,实现了对大气、水、植被等环境要素的实时监测与智能调控,为园区的绿色发展提供了有力保障。此外,方案还提出了建立全域旅游营销平台,整合区域旅游资源,推动旅游业与其他产业的深度融合,为区域经济的转型升级注入了新的活力。 总而言之,这份智慧园区建设方案以其前瞻性的理念、创新性的技术和人性化的服务设计,为我们展示了一个充满智慧与活力的未来园区图景。它不仅提升了园区的运营效率和服务质量,更让科技真正融入了人们的生活,带来了前所未有的便捷与舒适。对于正在规划或实施智慧园区建设的决策者而言,这份方案无疑提供了一份宝贵的参考与启示,激发了他们对于未来智慧生活的无限遐想与憧憬。
使用 SignalR 在 .NET Core 8 最小 API 中构建实时通知,构建实时应用程序已成为现代 Web 开发中必不可少的部分,尤其是对于通知、聊天系统和实时更新等功能。SignalR 是 ASP.NET 的一个强大库,可实现服务器端代码和客户端 Web 应用程序之间的无缝实时通信。 参考文章:https://blog.csdn.net/hefeng_aspnet/article/details/145990801
自适应网址导航网站发布页单页网页模板html源码,超级好看自适应清新网址导航网站发布页单页网页模板html源码!无论电脑还是手机,这是一个网页单页源码!! 模板无后台模板,无需数据库,上传服务器直接能用。
不用花钱,不拐弯抹角。