本文以图示的方式简单介绍了如何使用Java来实现心跳程序,心跳的英文单词是heartbeat. 心跳的目的是当客户端第一次向服务器端发送了请求后,在一定时间内服务器端未能将响应返回到客户端,那么客户端为了继续保持和服务器端的连接,这时客户端就会发送一个心跳到服务器端来维持这种连接,我个人的理解心跳其实也是一种请求,只不过这个请求并不携带要求服务器端要进行处理的信息(个人看法,仅供参考)。
好了,下面我就把客户端和服务器端的程序共享出来供大家参考。说明一下,我采用的是https响应方式,所以我会把详细的步骤呈现出来。我的操作系统是英文的,大家就将就着看吧,不过有截图,看起来也很方便啦!
1. 创建https服务器端所需要的证书。https是一种安全链接协议,所以在服务器端需要一个证书,关于这方面的知识大家可以去参考更为专业和详细的介绍,在这里就简单跳过了。
1.1. startrun
1.2. 在下列界面中输入”cmd”, 点击”Ok”
1.3. 输入创建证书的命令(Windows和Unix系统都适用) keytool -genkey -alias test -keyalg RSA -keystore D:/mykey.store, 这样就会在D:\下创建一个名为mykey.store的证书
说明:红框里面的都是要自己输入的,关键是密码,服务器端程序要使用到。
2. 服务器端程序
模式很固定,至于为什么要写成这样,you ask me, I ask whom, you’d better ask Google. 业务逻辑在class MyHandler的public void handle(HttpExchange t) throws IOException中实现。另外实现这个服务器端程序要用到 这是MyEclipse自带的,JDK1.6
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import sun.net.httpserver.HttpsServerImpl;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpsConfigurator;
publicclass HttpsServer {
publicstaticvoid main(String[] args) {
com.sun.net.httpserver.HttpsServer hss;
try {
//Set port as 8000
hss = HttpsServerImpl.create(new InetSocketAddress(8000),0);
//Create certification lib
KeyStore ks = KeyStore.getInstance("JKS");
// Load certification
ks.load(new FileInputStream("D:/key.store" ), "123456".toCharArray());
//Create a KeyManageeFactory
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
//Initialize the KeyManageeFactory
kmf.init(ks, "123456".toCharArray());
//Create certification instance
SSLContext sslContext = SSLContext.getInstance("SSLv3");
//Initialize certification
sslContext.init(kmf.getKeyManagers(), null, null);
//Confighttps
HttpsConfigurator conf = new HttpsConfigurator(sslContext);
//Load configuration in https server
hss.setHttpsConfigurator(conf);
// creates a default executor
hss.setExecutor(null);
// apply MyHandler to process "/" request
hss.createContext("/mytest", new MyHandler());
hss.start();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
}
class MyHandler implements HttpHandler{
privateintcount;
publicvoid handle(HttpExchange t) throws IOException {
InputStream is = t.getRequestBody();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String msg = null;
while ((msg = br.readLine()) != null) {
System.out.println("Request from client: " + msg);
}
is.close();
br.close();
count ++;
System.out.println("count: " + count);
String response1 = "first";
String response2 = "second";
t.sendResponseHeaders(200, 200);
OutputStream os = t.getResponseBody();
try {
if (count == 1) {
System.out.println("First send response to client");
Thread.sleep(6000);
os.write(response1.getBytes());
} elseif (count == 2){
System.out.println("Second send response to client");
// Thread.sleep(6000);
Thread.sleep(2000);
os.write(response2.getBytes());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
os.flush();
os.close();
}
}
3. 客户端程序
如果把本机作为服务器,url中的服务器地址理论上可以写成实际IP或127.0.0.1或localhost, 但有时写成实际的IP, 程序会出问题,就不得不写成127.0.0.1或localhost, 至于原因嘛,you ask me, I ask whom, you’d better ask Google, 因为我就是个打酱油的。多看我写的注释,关键代码就是那一句啊
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
publicclass HttpsClient {
privatestatic String url = "https://127.0.0.1:8000/mytest";
private myX509TrustManager xtm = new myX509TrustManager();
private myHostnameVerifier hnv = new myHostnameVerifier();
public HttpsClient() {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS"); // 或SSL
X509TrustManager[] xtmArray = new X509TrustManager[] { xtm };
sslContext.init(null, xtmArray, new java.security.SecureRandom());
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
if (sslContext != null) {
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
.getSocketFactory());
}
HttpsURLConnection.setDefaultHostnameVerifier(hnv);
}
privateintcount = 0;
publicvoid send(String msg) {
count ++;
HttpsURLConnection urlCon = null;
OutputStream os = null;;
InputStream is = null;
BufferedReader br = null;
try {
urlCon = (HttpsURLConnection) new URL(url).openConnection();
urlCon.setDoOutput(true);
urlCon.setRequestProperty("Content-Length", "1024");
urlCon.setUseCaches(false);
urlCon.setDoInput(true);
urlCon.setRequestMethod("POST");
// key point, set response time.
urlCon.setReadTimeout(5000);
os = urlCon.getOutputStream();
os.write(msg.getBytes());
os.flush();
os.close();
is = urlCon.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println("Response from server: " + line);
System.exit(0);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
if (count == 1) {
System.out.println("Send heartbeat");
send("Heartbeat");
} elseif (count == 2) {
System.out.println("Time is up");
}
} finally {
urlCon.disconnect();
try {
os.close();
is.close();
br.close();
} catch (IOException e) {}
}
}
publicstaticvoid main(String[] args) {
HttpsClient t = new HttpsClient();
System.out.println("Send request to server");
// try {
// Thread.sleep(6000);
t.send("Hello Server");
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
class myX509TrustManager implements X509TrustManager {
publicvoid checkClientTrusted(X509Certificate[] chain, String authType) {}
publicvoid checkServerTrusted(X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {
returnnull;
}
}
class myHostnameVerifier implements HostnameVerifier {
publicboolean verify(String hostname, SSLSession session) {
returntrue;
}
}
}
相关推荐
Spring Cloud 服务注册 Eureka 实现过程图解 Eureka 是 Netflix 开发的一个基于 REST 服务的服务注册和发现组件。主要包括两个组件:Eureka Server 和 Eureka Client。Eureka Server 是注册中心,提供服务注册和...
5. 使用 @EnableDiscoveryClient 注解使得应用程序变成 Eureka 客户端。 6. Eureka Server 的配置信息包括服务注册地址、服务发现地址、心跳检测间隔时间等。 7. Eureka 客户端的配置信息包括服务注册地址、服务发现...
Netty是当前非常流行的网络通讯框架,当程序对网络数据处理时,需要保证高并发和高可靠,底层就可以用Netty支撑。本套课程详细讲解了Netty核心技术点,同时进行底层机制和源码剖析,并编写了大量的应用实例。通过...
scratch少儿编程逻辑思维游戏源码-上下飞行.zip
kkzhilu_Code-Generate_32152_1745864907745
艺术博客_SpringSpringMVCMybatisShirojQueryBootstrapechartswebuploaderlayui_博客管理图表数据日
scratch少儿编程逻辑思维游戏源码-面具古墓.zip
scratch少儿编程逻辑思维游戏源码-时钟上的冰块.zip
健康监测_Android开发_BLE蓝牙通信_心率数据采集与存储_基于小米手环2的实时心率监测应用_支持后台长时间运行的心率记录工具_可导出SQLite数据库的心率数据分析系统_适
scratch少儿编程逻辑思维游戏源码-梦魇忍者.zip
scratch少儿编程逻辑思维游戏源码-谁建得更高.zip
scratch少儿编程逻辑思维游戏源码-忍者攀登.zip
模拟端 后端 qt前端
数据可视化_Android原生Canvas绘图_3D与非3D柱形图饼图折线图面积图曲线图环形图玫瑰图雷达图散点图气泡图仪表盘刻度盘漏斗图象限图_支持手势缩放滑动交互多图叠加动画效果
scratch少儿编程逻辑思维游戏源码-米克 demo.zip
聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程 系统采用FastAdmin框架独立全新开发,安全稳定,系统支持代理、商户、码商等业务逻辑。 针对最近一些JD,TB等业务定制,子账号业务逻辑API 非常详细,方便内置对接! IP白名单 业务逻辑 支持IP白名单,黑名单,全局白名单,全局黑名单,保障系统的安全。 接口验签名 采用支付宝RSA加密接口方式,防止篡改数据,导致对账困难,资金大量损失,无故少钱 对接灵活 全部对接参数灵活操作 风控完善 轮询、交易金额、随机金额、最大金额、最小金额等 测试环境: Nginx+PHP7.0+MySQL5.6 网站运行目录:/public 伪静态设置为:thinkphp规则 数据库信息修改路径:/application/database.php
第一步 package.json 下载这三个包 shelljs :执行 shell命令 ssh2-sftp-client 与服务器建立链接(内部有ssh2) chalk 打印彩色输出 第二步 配置脚本命令 deploy 注意后边加上运行环境 执行deploy命令时内部执行了打包动作 「 "deploy": "node deploy/index.js --prod」 第三步准备服务器密码 账号 部署地址 备份地址等等 参考如下 放到 config.js 中 module.exports = [ { id: 0, nodeEnv: "prod", name: "正式环境", domain: "", host: "ip", port: 端口, username: "用户名", password: "密码", path: "/data/www/paccount",//部署路径 removepath: "/data/www/paccount", //删除路径 }, ]; 第四步 如果需要在服务器执行命令 在部署完成后执行 chmodDir 自行决定
scratch少儿编程逻辑思维游戏源码-恐怖矿井.zip
scratch少儿编程逻辑思维游戏源码-爬墙鸟.zip
scratch少儿编程逻辑思维游戏源码-亮灯.zip