长轮询java_网络编程-轮询和长轮询
轮询(Polling):是指不管服务器端有没有更新,客户端(通常是指浏览器)都定时的发送请求进行查询,轮询的结果可能是服务器端有新的更新过来,也可能什么也没有,只是返回个空的信息。不管结果如何,客户端处理完后到下一个定时时间点将继续下一轮的轮询。
长轮询(Long Polling):长轮询的服务其客户端是不做轮询的,客户端在发起一次请求后立即挂起,一直到服务器端有更新的时候,服务器才会主动推送信息到客户端。 在服务器端有更新并推送信息过来之前这个周期内,客户端不会有新的多余的请求发生,服务器端对此客户端也啥都不用干,只保留最基本的连接信息,一旦服务器有更新将推送给客户端,客户端将相应的做出处理,处理完后再重新发起下一轮请求。
可见,长轮询的特点:
服务器端会阻塞请求直到有数据传递或超时才返回.
客户端响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接.
当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。
Java-长轮询(Long polling)实现
服务端
package _20200418.example;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
* 长轮询服务端
*
* Created by zfh on 2020/04/18
*/
public class server {
private final AtomicLong value = new AtomicLong();
private void start() throws IOException {
HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 0);
httpServer.setExecutor(Executors.newCachedThreadPool());
httpServer.createContext("/long-polling", httpExchange -> {
byte[] data = fetchData();
httpExchange.sendResponseHeaders(200, data.length);
OutputStream outputStream = httpExchange.getResponseBody();
outputStream.write(data);
outputStream.close();
httpExchange.close();
});
httpServer.start();
}
private byte[] fetchData() {
try {
// 由于客户端设置的超时时间是50s,
// 为了更好的展示长轮询,这边random 100,模拟服务端hold住大于50和小于50的情况。
Random random = new Random();
TimeUnit.SECONDS.sleep(random.nextInt(100));
} catch (InterruptedException ignored) {
}
return Long.toString(value.getAndIncrement()).getBytes(StandardCharsets.UTF_8);
}
public static void main(String[] args) throws IOException {
server server = new server();
server.start();
}
}
客户端
package _20200418.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicLong;
/**
* 长轮询-客户端
*
* Created by zfh on 2020/04/18
*/
public class client {
private static final String SYNC_URL = "http://localhost:8080/long-polling";
private final AtomicLong sequence = new AtomicLong();
void poll() {
// 循环执行,保证每次longpolling结束,再次发起longpolling
// 结束条件,超时或者拿到数据
while (!Thread.interrupted()) {
doPoll();
}
}
private void doPoll() {
System.out.println("第" + (sequence.incrementAndGet()) + "次 longpolling");
long startMillis = System.currentTimeMillis();
HttpURLConnection connection = null;
try {
URL getUrl = new URL(SYNC_URL);
connection = (HttpURLConnection) getUrl.openConnection();
// 50s作为长轮询超时时间
connection.setReadTimeout(50000);
connection.setConnectTimeout(3000);
connection.setRequestMethod("GET");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
connection.connect();
if (200 == connection.getResponseCode()) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
StringBuilder result = new StringBuilder(256);
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
System.out.println("结果 " + result);
} finally {
if (reader != null) {
reader.close();
}
}
}
} catch (IOException e) {
System.out.println("request failed");
} finally {
long elapsed = (System.currentTimeMillis() - startMillis) / 1000;
System.out.println("connection close" + " " + "elapse " + elapsed + "s");
if (connection != null) {
connection.disconnect();
}
System.out.println();
}
}
public static void main(String[] args) throws InterruptedException {
client bootstrap = new client();
bootstrap.poll();
Thread.sleep(Integer.MAX_VALUE);
}
}
长轮询java_网络编程-轮询和长轮询相关推荐
- Linux网络编程 | 高性能定时器 :时间轮、时间堆
文章目录 时间轮 时间堆 在上一篇博客中我实现了一个基于排序链表的定时器容器,但是其存在一个缺点--随着定时器越来越多,添加定时器的效率也会越来越低. 而下面的两个高效定时器--时间轮.时间堆,会完美 ...
- 第十四章:Java_网络编程
网络编程概述: Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序. Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节 ...
- Java_常瑞鹏 java_网络编程实现一个 聊天程序
网络编程 l网络模型 OSI参考模型 TCP/IP参考模型 l网络通讯要素 IP地址 端口号 传输协议 网络参考模型 网络通讯要素 lIP地址:InetAddress 网络中设备的标识 不易记忆,可用 ...
- 网络编程java_网络编程基础
在学习Java网络编程之前,我们先来了解什么是计算机网络. 计算机网络是指两台或更多的计算机组成的网络,在同一个网络中,任意两台计算机都可以直接通信,因为所有计算机都需要遵循同一种网络协议. 那什么是 ...
- JAVA网络编程Socket常见问题 【长连接专题】
一. 网络程序运行过程中的常见异常及处理 第1个异常是 java.net.BindException:Address already in use: JVM_Bind. 该异常发生在服务器端进行new ...
- bootstrap外不引用连接_网络编程Netty IoT百万长连接优化,万字长文精讲
IoT是什么 The Internet of things的简称IoT,即是物联网的意思 IoT推送系统的设计 比如说,像一些智能设备,需要通过APP或者微信中的小程序等,给设备发送一条指令,让这个设 ...
- 【性能优化】网络编程 - PHP - 使用TCP长连接的一种优化思路 - 学习/实践
1.应用场景 主要了解学习如何基于PHP使用TCP长连接的一种优化思路. 2.学习/参考 文档阅读 PHP - CGI, Fast-FGI, PHP-FPM - 学习/实践 php使用tcp长连接的一 ...
- socket connect java_网络编程 – 为什么Java的socket.connect()消耗100%的cpu资源?
我创建了一个线程池并为它提供了50个连接到服务器的任务.所以一旦完成连接,发送一些数据,然后断开连接.它的读取超时设置为5秒(当然是5000长).我甚至将线程池设置为最大大小为1.然后在 linux上 ...
- java_网络编程学习笔记(一)
网络概述 网络模型 了解更多OSI模型和TCP/IP模型参考http://blog.csdn.net/yuliu0552/article/details/6711659 IP地址 package cn ...
最新文章
- Exchange 2013 OWA搜索邮件失败问题处理
- AutoRunner视图模式的合理使用
- 日志中的秘密 Windows登录类型都有哪些
- 计算机主板风扇安装,5个装机注意事项 让你装电脑少走弯路
- ssm使用全注解实现增删改查案例——DeptMapperImpl
- XMPP之openfire无法启动
- tensorflow1、2会话、变量、feed、fetch、最小二乘法
- simplifyEnrichment,一个对GO富集结果进行聚类和可视化的工具
- 产品定额的一些陷阱思考
- matlab动态图最新存储文件,MATLAB 动图绘制、保存
- RR调度(Round-robin scheduling)简单介绍
- Matlab Tricks(七)—— 矩阵列/列的归一化/单位化(normalize)
- 支持跨域的html元素
- matlab遥感图像 提取地物,基于MATLAB的遥感图像变化监测研究(图文)
- 【模块化那些事】 拆散的模块化
- 小虎队《爱》 —— 米扑科技公司司歌
- 域环境批量推送OUTLOOK签名
- python 网络通讯 plc_Python TCP通信网络编程
- BASE32编码 --记录
- 身份证OCR识别工作原理及流程