长轮询的使用实现_长轮询和短轮询

长轮询的使用实现_长轮询和短轮询轮询(Polling):是指不管服务器端有没有更新,客户端(通常是指浏览器)都定时的发送请求进行查询,轮询的结果可能是服务器端有新的更新过来,也可能什么也没有,只是返回个空的信息。不管结果如何,客户端处理完后到下一个定时时间点将继续下一轮的轮询。长轮询(LongPolling):长轮询的服务其客户端是不做轮询的,客户端在发起一次请求后立即挂起,一直到服务器端有更新的时候,服务器才会主动推送信息到…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

轮询(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);

}

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/230792.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • javascript 之 prototype与__proto__

    javascript 之 prototype与__proto__

    2022年3月13日
    40
  • linux练习题

    观察系统当前进程的运行情况的命令是():A、freeB、dmesgC、topD、last答案:http://hovertree.com/tiku/bjag/foxg5n0q.htmLinux系统

    2021年12月28日
    33
  • 设置PyCharm使用Anaconda的环境[通俗易懂]

    设置PyCharm使用Anaconda的环境[通俗易懂]设置PyCharm使用Anaconda的环境PyCharm的安装以及Anaconda的安装和环境的新建这里就不做赘述了。为每一个PyCharm中的project设置特定的编译器及资源路径在PyCharm中新建一个project后,该项目的默认编译器应该是系统默认的python.exe。为了选择特定的编译环境,我们需要个性化设置一下。首先点击菜单栏中的File,打开Settings。在Pr…

    2022年8月28日
    2
  • DNS负载均衡和NGINX负载均衡「建议收藏」

    DNS负载均衡和NGINX负载均衡「建议收藏」负载均衡:把请求均匀的分摊到多个服务器上处理DNS负载均衡DNS负载均衡是通过DNS服务器实现的,主要用于把请求均匀的分布到nginx服务器上,真实情况可能是根据区域区分请求,但是一个地域中请求还是需要均匀的分配到nginx服务器上实现原理:DNS服务器为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将…

    2022年7月14日
    56
  • docker mysql 启动失败_mysql启动1067错误

    docker mysql 启动失败_mysql启动1067错误docker启动mysql失败,报错dockerexec-itmysqlmysql-uroot-prootErrorresponsefromdaemon:Container0f83eee59a75595deedecbd40b384333e6db35edd90c5d4c3a0eb3212f2e4665isrestarting,waituntilthecontainerisrunning一直显示正在重启使用dockerlogs–tail50–follow-

    2022年10月6日
    3
  • centos7 安装gitea使用

    centos7 安装gitea使用参考官网 https gitea iohttps docs gitea iohttps docs gitea io en us install from binary 关于 GiteaGitea 是一个自己托管的 Git 服务程序 他和 GitHub BitbucketorG 等比较类似 他是从 Gogs 发展而来 不过我们已经 Fork 并且命名为 Gitea 对

    2025年9月25日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号