- 浏览: 85156 次
- 性别:
- 来自: 北京
最新评论
-
zhulongxia:
您好,请问您的服务端的配置和用flex写客户端的配置一样么?还 ...
Red5 Client 调用 Red5 Server -
zhaoleiJE:
public static String toMPTree(S ...
jave -
zouwu85:
你好,你这个能录制网络上的flv小游戏的数据吗?
使用Red5 录制视频 -
emilyHong:
不过有没有多条线的?
js曲线图 -
amssy_zhu:
很好,正准备开发这样的系统
使用Java实现Comet风格的Web应用
最近开始研究jetty 7。已经出到稳定版了。我相信大多JETTY的爱好者已经看过了。
这里呢。对jetty
7的continuation总结一下。
为了做一个server long
push的WEB应用。我选择了jetty。对于Jetty,我只能说是一个新手,在网上搜资料的时候,发现相关资料少个可怜,中文的资料都是一个抄一
个,或者就是翻译的。对于jetty我走了弯路。迫使自己看是看jetty的源文件。
大家肯定都知道jetty的
continuation是建立的NIO技术的基础上。使WEB
服务器对大量的HTTP申请做阻塞不必开启过多的线程。避免了浪费。而jetty是将封装好的servlet加入一个等待队列。之后做轮询。哪个满足条
件。就调用用户的方法去操作response。
刚开始作为一个第一次用jetty的人,我把suspend/complete和
suspend/resunme产生了一个错误的理解。我以为这个方法只是阻塞申请。于是我建立了一个方法。里面做了一个循环去判断某个值,如果存在就反
馈并complete。而最后发现jetty自带了遍历的功能。不用你去写循环。
正确的写法如下:
//判断applition中是否有msg有的话反馈,没有的话就阻塞。 protected void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { //得到applition对象 ServletContext applition = getServletConfig().getServletContext(); //获取continuation Continuation continuation = ContinuationSupport.getContinuation(request); //设定超时时间、可以不设置。默认为30秒 continuation.setTimeout(0); //阻塞 continuation.suspend(); //如果applition中有msg这个字符。开放阻塞 if(applition.getAttribute("msg").toString() != null){ continuation.complete(); response.getServletResponse().getWriter().print( applition.getAttribute("msg").toString() ); } }
其他你都不用管。服务器会做循环来调用你的serlvet。然后调用你的判断方法做处理。
要注意的一点是:
我做了一个小小的
测试。我挂起了20个长连接去判断自己需求的信息,但是呢。我第一步就给与第9个长连接做判断的对象赋值,按理论上来说,它应该立即反馈的。
错!
它不会反馈给你。因为服务器端对每个客户端挂起的长连接做了限制。代码如下:
package org.eclipse.jetty.continuation; import java.util.ArrayList; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.ServletResponseWrapper; class FauxContinuation implements ContinuationFilter.FilteredContinuation { private static final ContinuationThrowable __exception = new ContinuationThrowable(); //这里就是限制你为什么不能一台机器申请挂起多个长连接的原因。 private static final int __HANDLING = 1; private static final int __SUSPENDING = 2; private static final int __RESUMING = 3; private static final int __COMPLETING = 4; private static final int __SUSPENDED = 5; private static final int __UNSUSPENDING = 6; private static final int __COMPLETE = 7; private final ServletRequest _request; private ServletResponse _response; private int _state = 1; private boolean _initial = true; private boolean _resumed = false; private boolean _timeout = false; private boolean _responseWrapped = false; private long _timeoutMs = 30000L; private ArrayList<ContinuationListener> _listeners; FauxContinuation(ServletRequest request) { this._request = request; } public void onComplete() { if (this._listeners != null) for (ContinuationListener l : this._listeners) l.onComplete(this); } public void onTimeout() { if (this._listeners != null) for (ContinuationListener l : this._listeners) l.onTimeout(this); } public boolean isResponseWrapped() { return this._responseWrapped; } public boolean isInitial() { synchronized (this) { return this._initial; } } public boolean isResumed() { synchronized (this) { return this._resumed; } } public boolean isSuspended() { synchronized (this) { switch (this._state) { case 1: return false; case 2: case 3: case 4: case 5: return true; case 6: } return false; } } public boolean isExpired() { synchronized (this) { return this._timeout; } } public void setTimeout(long timeoutMs) { this._timeoutMs = timeoutMs; } public void suspend(ServletResponse response) { this._response = response; this._responseWrapped = response instanceof ServletResponseWrapper; suspend(); } public void suspend() { synchronized (this) { switch (this._state) { case 1: this._timeout = false; this._resumed = false; this._state = 2; return; case 2: case 3: return; case 4: case 5: case 6: throw new IllegalStateException(getStatusString()); } throw new IllegalStateException("" + this._state); } } public void resume() { synchronized (this) { switch (this._state) { case 1: this._resumed = true; return; case 2: this._resumed = true; this._state = 3; return; case 3: case 4: return; case 5: fauxResume(); this._resumed = true; this._state = 6; break; case 6: this._resumed = true; return; default: throw new IllegalStateException(getStatusString()); } } } public void complete() { synchronized (this) { switch (this._state) { case 1: throw new IllegalStateException(getStatusString()); case 2: this._state = 4; break; case 3: break; case 4: return; case 5: this._state = 4; fauxResume(); break; case 6: return; default: throw new IllegalStateException(getStatusString()); } } } public boolean enter(ServletResponse response) { this._response = response; return true; } public ServletResponse getServletResponse() { return this._response; } void handling() { synchronized (this) { this._responseWrapped = false; switch (this._state) { case 1: throw new IllegalStateException(getStatusString()); case 2: case 3: throw new IllegalStateException(getStatusString()); case 4: return; case 5: fauxResume(); case 6: this._state = 1; return; } throw new IllegalStateException("" + this._state); } } public boolean exit() { synchronized (this) { switch (this._state) { case 1: this._state = 7; onComplete(); return true; case 2: this._initial = false; this._state = 5; fauxSuspend(); if ((this._state == 5) || (this._state == 4)) { onComplete(); return true; } this._initial = false; this._state = 1; return false; case 3: this._initial = false; this._state = 1; return false; case 4: this._initial = false; this._state = 7; onComplete(); return true; case 5: case 6: } throw new IllegalStateException(getStatusString()); } } protected void expire() { synchronized (this) { this._timeout = true; } onTimeout(); synchronized (this) { switch (this._state) { case 1: return; case 2: this._timeout = true; this._state = 3; fauxResume(); return; case 3: return; case 4: return; case 5: this._timeout = true; this._state = 6; break; case 6: this._timeout = true; return; default: throw new IllegalStateException(getStatusString()); } } } private void fauxSuspend() { long expire_at = System.currentTimeMillis() + this._timeoutMs; long wait = this._timeoutMs; while ((this._timeoutMs > 0L) && (wait > 0L)) { try { super.wait(wait); } catch (InterruptedException e) { break label51: } wait = expire_at - System.currentTimeMillis(); } if ((this._timeoutMs > 0L) && (wait <= 0L)) label51: expire(); } private void fauxResume() { this._timeoutMs = 0L; super.notifyAll(); } public String toString() { return getStatusString(); } String getStatusString() { synchronized (this) { return ((this._state == 4) ? "COMPLETING" : (this._state == 6) ? "UNSUSPENDING" : (this._state == 3) ? "RESUMING" : (this._state == 5) ? "SUSPENDED" : (this._state == 2) ? "SUSPENDING" : (this._state == 1) ? "HANDLING" : new StringBuilder().append("???").append(this._state).toString()) + ((this._initial) ? ",initial" : "") + ((this._resumed) ? ",resumed" : "") + ((this._timeout) ? ",timeout" : ""); } } public void addContinuationListener(ContinuationListener listener) { if (this._listeners == null) this._listeners = new ArrayList(); this._listeners.add(listener); } public Object getAttribute(String name) { return this._request.getAttribute(name); } public void removeAttribute(String name) { this._request.removeAttribute(name); } public void setAttribute(String name, Object attribute) { this._request.setAttribute(name, attribute); } public void undispatch() { if (isSuspended()) { if (ContinuationFilter.__debug) throw new ContinuationThrowable(); throw __exception; } throw new IllegalStateException("!suspended"); } }
所以遇到这个问题的朋友不必担心。我使用多台机器测试过。服务器的servlet轮询队列是很长的。但对于单独用户来说只能接受6个
suspend.在发送长连接挂起请求。他们加入到你所处的用户等待列表。当你挂起的6个连接中有一个被释放了。你的第7个连接将被挂起。
之
前用了webbench做压测。
不管你怎么测非阻塞技术的长连接。你都会被jetty拒之门外。。。
就是因为这个做
了限制。这样的限制大大降低对服务器的压力。
发表评论
-
red5检测流量
2010-07-16 17:27 1332@Override public void strea ... -
red5共享对象
2010-07-16 17:21 1799package ChatSystem; import java ... -
red5+hibernate
2010-07-16 17:18 1395Application 代码: package conjs.i ... -
使用Red5 录制视频
2010-07-16 17:17 4647import java.io.File; import or ... -
Red5实现直播
2010-07-16 17:14 9869发布端(Publish): var nc:NetConnect ... -
Red5 Client 调用 Red5 Server
2010-07-16 17:02 2913package com.conjs; import org. ... -
jave
2010-07-14 10:56 1317JAVE (Java Audio Video Encoder) ... -
nutch+solr
2010-07-13 17:52 1592两年前集成Nutch 和Solr 这两个Apache Luc ... -
ActiveMQ
2010-07-13 17:44 46251. 背景 ... -
red5的一些概念
2010-07-09 10:52 1291IConnection 是连接的意思 并且有getClient ... -
red5的eclipse插件地址
2010-07-09 10:05 1171Name: Red5Plugin 0.2.x (Eclipse ... -
uuid
2010-07-06 17:55 1076java uuid生成方法 UUID(Universally ... -
Java集合排序及java集合类详解:集合框架中常用类比较
2010-07-01 14:06 1979用 “ 集合框架 ” 设计软件时,记住该框架四个 ... -
Java集合排序及java集合类详解:Set
2010-07-01 14:04 14821.5 Set 1.5.1 概述 ... -
Java集合排序及java集合类详解:Map
2010-07-01 14:02 21601.4 Map 1.4.1 概 ... -
Java集合排序及java集合类详解:Collection
2010-07-01 13:50 21431.2 Collection ... -
Java集合排序及java集合类详解:集合框架概述
2010-07-01 13:47 12911.1 集 ... -
关于 Java Collections API 您不知道的 5 件事,第 2 部分
2010-06-29 13:57 676java.util 中的 Collection ... -
关于 Java Collections API 您不知道的 5 件事,第 1 部分
2010-06-29 13:55 798对于很多 Java 开发人员 ... -
关于 Java 对象序列化您不知道的 5 件事
2010-06-29 11:59 863数年前,当和一个软件团队一起用 Java 语言编写一个应用程序 ...
相关推荐
赠送jar包:jetty-continuation-8.1.8.v20121106.jar; 赠送原API文档:jetty-continuation-8.1.8.v20121106-javadoc.jar; 赠送源代码:jetty-continuation-8.1.8.v20121106-sources.jar; 赠送Maven依赖信息文件:...
jetty-continuation-7.4.2.v20110526.jar jetty 服务jar包
赠送jar包:jetty-continuation-8.1.8.v20121106.jar; 赠送原API文档:jetty-continuation-8.1.8.v20121106-javadoc.jar; 赠送源代码:jetty-continuation-8.1.8.v20121106-sources.jar; 赠送Maven依赖信息文件:...
jetty-security-9.4.8.v20171121.jar,jetty-io-9.4.8.v20171121.jar,jetty-continuation-9.4.8.v20171121.jar,jetty-client-9.4.8.v20171121.jar,jetty-jmx-9.4.8.v20171121.jar,jetty-plus-9.4.8.v20171121....
java运行依赖jar包
Jetty cometd(Continuation)学习笔记,自己用的,别人那down的网页
这个压缩包包含Jetty 8版本的实现及其依赖库,是学习和理解Jetty工作原理,尤其是NIO(非阻塞I/O)和Servlet容器实现的宝贵资源。 Jetty 8在设计时特别强调了性能和可扩展性,它使用了Java NIO(New I/O)API来处理...
总结,Jetty 7.4.2是一个针对Servlet 3.0标准的Web服务器,具有高性能、易用和可扩展的特性。对于开发者来说,这是一个理想的选择,尤其适合于需要轻量级、快速部署的Web应用。通过下载并使用jetty-distribution-...
java运行依赖jar包
java运行依赖jar包
java运行依赖jar包
java运行依赖jar包
org.eclipse.jetty.continuation_9.1.1.v20140108.jar org.eclipse.jetty.continuation.source_9.1.1.v20140108.jar org.eclipse.jetty.deploy_9.1.1.v20140108.jar org.eclipse.jetty.deploy.source_9.1.1.v...
Jetty由Eclipse基金会维护,是Java社区中的一个重要组件,尤其在嵌入式系统和微服务领域中备受青睐。下面我们将深入探讨Jetty的核心特性、与Tomcat的对比以及如何使用。 1. **Jetty的核心特性** - **轻量级**:...
Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立...
赠送jar包:jetty-client-9.4.43.v20210629.jar; 赠送原API文档:jetty-client-9.4.43.v20210629-javadoc.jar; 赠送源代码:jetty-client-9.4.43.v20210629-sources.jar; 赠送Maven依赖信息文件:jetty-client-...
Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立...
注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 ...
7. **IDE Integration**:对于Eclipse和IntelliJ IDEA这样的集成开发环境(IDE),Jetty有专门的插件,便于开发者在IDE内部直接调试和运行Jetty应用。 此压缩包的文件名列表"jetty-hightide-8.1.15.v20140411"暗示...