相关文章
更多最近更新
更多comet基于长连接流实现服务器端反向推数据的方式
2019-03-03 13:15|来源: 领悟书生
comet用来解决服务器端反向推数据
目前有多种方式可以实现
1.长连接
基于长连接流的方式
基于长轮询的方式
2.websocket
这一节我们说基于长连接流的方式实现服务端反向推数据
1.修改tomcat,让其可以支持NIO方式
直接修改server.xml里的Connector节点,修改protocol为org.apache.coyote.http11.Http11NioProtocol
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />
2.创建servlet,让其实现org.apache.catalina.CometProcessor
不用实现doGet()和doPost()
package com.naxsu.comet.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.CometEvent; import org.apache.catalina.CometProcessor; public class SecondServlet extends HttpServlet implements CometProcessor { private static final long serialVersionUID = 1L; public void event(CometEvent event) throws IOException{ /* * event方法用来处理各种请求,可以根据状态的不同得到各种响应 * 同时可以不断根据自己的需求像客户端发送信息 */ HttpServletResponse resp = event.getHttpServletResponse(); HttpServletRequest req = event.getHttpServletRequest(); //对于event而言,会存在多种状态,在begin的时候可以开始获取数据 if(event.getEventType()==CometEvent.EventType.BEGIN) { System.out.println(req.getSession().getId()); //在begin的状态进行数据写操作 log(req.getSession().getId()+"连接建立成功"); new Thread(new RandomThread(resp)).start(); } else if(event.getEventType()==CometEvent.EventType.END) { //请求结束的时候执行 log(req.getSession().getId()+"已经结束"); event.close(); } else if(event.getEventType()==CometEvent.EventType.ERROR) { //发送错误的时候处理 log(req.getSession().getId()+"发送错误"); event.close(); } else if(event.getEventType()==CometEvent.EventType.READ) { //还正读取数据的状态 throw new RuntimeException("该状态无法进行操作"); } } @Override public void init() throws ServletException { super.init(); } }
在建立连接成功的时候,用到一个线程类,来维护数据的反推
package com.naxsu.comet.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.Random; import javax.servlet.http.HttpServletResponse; public class RandomThread implements Runnable { private final static Random ran = new Random(); private boolean running = true; private HttpServletResponse connect; public RandomThread(HttpServletResponse connect) { this.connect = connect; } @Override public void run() { while(running) { try { Thread.sleep(5000); PrintWriter out = connect.getWriter(); int num = ran.nextInt(100); System.out.println("send:"+num); /* *基于流的方式由于整个过程仅仅用一个连接,所以全部都使用同一个 *response来进行传递,所以不能关闭流 */ out.println(num+""); //必须刷新 out.flush(); } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } }
3.页面发起请求进行连接,服务器不断的向页面抢着数据
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>基于长连接流的方式实现</title> <script type="text/javascript" src="js/jquery-1.9.0.js"></script> <script type="text/javascript"> $(function(){ var xhr = createXmlHttpRequest(); xhr.open("POST","second.do",true); //由于jquery没有办法支持不同的状态码的判断,所以需要通过原始的ajax来处理 var pos = 0; xhr.onreadystatechange = function() { //让状态码等于3就可以保证两端一直进行连接,这是实现长连接的stream的方式 if(xhr.readyState==3&&xhr.status==200) { //获取相应的文本:通过xhr的responseText可以获取文本信息,包括xml的标签 //通过responseXML可以获取xml的信息,只能xml对象 $("#content").append(xhr.responseText.substring(pos)+","); pos = xhr.responseText.length; } }; xhr.send(); }); function createXmlHttpRequest() { if(window.XMLHttpRequest) { //针对其他主流浏览器 return new XMLHttpRequest(); } else if(window.ActiveXObject) { //针对IE5和IE6 return new ActiveXObject("Microsoft.XMLHTTP"); } else { alert("你使用的浏览器不支持XMLHttpRequest,请换一个浏览器再试!"); return null; } } </script> </head> <body> <div id="content"></div> </body> </html>
页面效果如下:
也许你发现:google浏览器是不支持的
原因:
基于长连接的方式,由于状态码是在3的时候出来数据,对于很多浏览器而言并不支持在状态为处理中的时候传数据,所以,限制很大。
所以需要使用新的方式:长轮询的方式,这种方式,是目前使用最多的方式
本文链接:comet基于长连接流实现服务器端反向推数据的方式,由领悟书生原创
转载请注明出处【http://www.656463.com/article/364】
相关问答
更多-
JAVA SOCKET 服务器端如何发送图片流[2023-09-23]
用的是tcp传输还是UDP传输。和前面说的一样,socket通信传的byte,传输方法一样,都是outputStream,只是接受不一样,你只要用inputStream写成file就可以了。 没传完的话,理论上是可以显示部分数据的,看看现在浏览器的图片预览,lazy load就知道了。六帧是代表6张图么?如果是的话,你可以看网络传输速度和文件大小。 -
java里面什么是服务器端编程?[2023-05-08]
你写的程序放在服务器电脑上运行,叫做服务器端编程。 既然是叫做服务器,也说明你写的程序要可以接受客户端的互动。 你写的程序放在客户端上运行,叫做客户端编程。 -
服务器端的mysql数据库在哪里下载?[2021-07-07]
少上搜搜上搜搜上搜搜上搜搜上搜搜 -
JAVA SOCKET 服务器端如何发送图片流[2021-12-29]
用的是tcp传输还是UDP传输。和前面说的一样,socket通信传的byte,传输方法一样,都是outputStream,只是接受不一样,你只要用inputStream写成file就可以了。 没传完的话,理论上是可以显示部分数据的,看看现在浏览器的图片预览,lazy load就知道了。六帧是代表6张图么?如果是的话,你可以看网络传输速度和文件大小。 -
HttpClient 的Post 请求,服务器端的doPost方法怎么获取数据?[2022-10-23]
服务端和普通的servlet获得数据没有区别,就是通过request.getParameter()等API获得数据. 要知道: 服务端的代码与你是通过HttpClient请求还是浏览器请求都没有联系! -
什么是服务器端[2022-05-02]
简单的说,服务器端是为客户端服务的,服务的内容诸如向客户端提供资源,保存客户端数据等等.客户端可以是任意的一台电脑,只要它和服务器端存在连接,并且得到了服务器端的授权,就可以使用服务器端的服务.象现在就可以理解为百度的网站是服务器端,我们现在使用的电脑就是客户端.我们可以使用它的服务. 通常的服务器端都是服务器级的高级PC,以便多客户访问时不会造成延时甚至数据溢出. -
服务器端推[关闭](Server Side push [closed])[2022-02-24]
您可以使用开源的JWebSocket和基于HTML 5规范的服务器端推送的websocket。希望您可以查看http://jwebsocket.org/ 。 希望对你有帮助 you can use JWebSocket which is open source and websocket that will do server side push based on HTML 5 specification.Hope please check this link http://jwebsocket.org/. ... -
只要小心选择(没有冲突的端口等),使用的端口号就没有必要。 真正的问题是处理跨域请求。 由于端口在技术上位于另一台服务器上,因此我们面临跨域请求的问题。 因此,使用不同的端口号不是一个很好的解决方案。 事实证明反向代理并不像我想象的那样可怕,我只是将以下几行添加到htaccess: ProxyRequests Off ProxyPass /comet http://localhost:8888 ProxyPassReverse /comet http://localhost:8888 8888是我使用的 ...
-
实现Comet服务器端后端的最简单方法是什么?(What is the easiest way to implement a Comet serverside backend?)[2023-11-24]
扭曲非常强大但不易使用,特别是对于新手。 tornado是Python中的另一个异步服务器,不如Twisted通用(例如,你不会将它用于网络客户端 ),但更容易用于实现服务器,包括Comet服务器。 Twisted is very powerful but not easy to use, especially for a newbie. tornado is another async server in Python, less general than Twisted (you would not u ... -
我是一个渐进式学习者,所以当学习新技术时,我更喜欢用我已经知道的语言(反之亦然,尝试用新语言熟悉的东西),但是,嘿,有时我们需要大爆炸...... 您没有说明您已经知道的语言和编程模型。 Comet的本质分为三个部分: 在一段时间内增量生成一些数据 通过长时间连接提供数据的服务器功能 客户端能够请求数据并从长时间连接读取 通过以下方式向后工作: 客户端你可能是基于浏览器的,因此使用JavaScript。 如果您可以使用库来处理交付,那么服务器端可以节省大量工作。 有很多选择,我在Java工作,App Ser ...