论坛首页 Web前端技术论坛

Comet,下一代Ajax?

浏览 67885 次
该帖已经被评为良好帖
作者 正文
   发表时间:2006-10-26  
jerry.li 写道
pushlet 性能并不是很好,不知道dwr2.0的push做的怎么样。如果性能得不到提升,那末comet技术还是不用的好。

pushlet性能好不好咱没测试不好下结论,不过他的实现还是比较容易理解的,dwr 2.0所谓reverse ajax部分的源代码刚看完,在reverseAjax中使用的是poll方式来模拟push操作的,也就是在客户端使用setTimeout,不断的发送请求获取新的内容。至于性能好不好我不说大家也应该知道了
下面是dwr的java-chat demo中使用reverse ajax的几个关键代码点:
首先是在onload中进行设置
引用

<body onload="DWREngine.setReverseAjax(true);">


然后是engine.js中的代码
引用

DWREngine.setReverseAjax = function(reverseAjax) {
  DWREngine._reverseAjax = reverseAjax;
  if (DWREngine._reverseAjax) {
    DWREngine._triggerNextPoll(0);
  }
};

DWREngine._triggerNextPoll = function(pause) {
  setTimeout("DWREngine._poll()", pause);
}


_poll函数中就是发送请求了。


0 请登录后投票
   发表时间:2006-10-26  
ppeter 写道
我没有看过comet是什么东西,按照各位的讨论看来,这种技术可以运用到基于web的聊天程序实现.
最近几个月一直在做基于web的聊天程序,主要是运用了xmpp协议,关于这个协议的详细信息,大家不妨可以google一下.运用这个协议,有很多开源的组件包,比如smack.聊天的客户端和服务器端都有开源项目,我用过webchat,wildfire,等.推荐大家有需要的话可以去看看.

基于其他协议(非http协议)不在研究范围之内。
0 请登录后投票
   发表时间:2006-10-26  
mineral 写道

另外,http协议本身是无状态的,只是容器实现加上了httpSession的具体不同实现,而CometServer(不单指楼主的CometServer)要实时地保持着客户端连接的socket,保存request的状态信息,用户标识信息等,在性能上和实现难度上,是不是比http 的server实现,难度还要更高一点。欢迎大家热烈讨论



在看jetty的相关文档的时候,我发现了continuation(延续)这个东东,而continuation是java语言本身不支持的,jetty做到了这一点,目前我还没搞懂它与长连接之间是什么关系,在dwr 2.0的DwrSystem.java中看到了这样的代码:
static
    {
        try
        {
            continuationClass = LocalUtil.classForName("org.mortbay.util.ajax.Continuation"); //$NON-NLS-1$
            suspendMethod = continuationClass.getMethod("suspend", new Class[] { Long.TYPE }); //$NON-NLS-1$
            resumeMethod = continuationClass.getMethod("resume", new Class[] {}); //$NON-NLS-1$
            getObject = continuationClass.getMethod("getObject", new Class[] {}); //$NON-NLS-1$
            setObject = continuationClass.getMethod("setObject", new Class[] { Object.class }); //$NON-NLS-1$
        }
        catch (Exception ex)
        {
            log.debug("No Jetty ContuniationSupport class, using standard Servlet API"); //$NON-NLS-1$
        }
    }

... ...
public void pollPreStreamWait()
    {
        WebContext context = WebContextFactory.get();
        Container container = context.getContainer();

        final ScriptSession scriptSession = context.getScriptSession();
        ServerLoadMonitor monitor = (ServerLoadMonitor) container.getBean(ServerLoadMonitor.class.getName());
        long sleepTime = monitor.timeWithinPollPreStream();

        synchronized (scriptSession.getScriptLock())
        {
            // Don't wait if there are queued scripts
            if (scriptSession.getQueuedScripts() > 0)
            {
                return;
            }

            // If this is Jetty then we can use Continuations
            HttpServletRequest request = context.getHttpServletRequest();

            boolean useSleep = true;
            Object continuation = request.getAttribute(ATTRIBUTE_JETTY_CONTINUATION);
            if (continuation != null)
            {
                useSleep = false;

                try
                {
                    // create a listener 
                    ScriptConduit listener = (ScriptConduit) getObject.invoke(continuation, new Object[0]);
                    if (listener == null)
                    {
                        listener = new SystemScriptConduit(continuation);
                        setObject.invoke(continuation, new Object[] { listener });
                    }
                    scriptSession.addScriptConduit(listener);

                    // continuation.suspend(sleepTime);
                    // NB. May throw a Runtime exception that must propogate to the container!
                    suspendMethod.invoke(continuation, new Object[] { new Long(sleepTime) });
                }
                catch (InvocationTargetException ex)
                {
                    ContinuationUtil.rethrowIfContinuation(ex.getTargetException());

                    log.warn("Error in Reflection", ex.getTargetException()); //$NON-NLS-1$
                    useSleep = true;
                }
                catch (Exception ex)
                {
                    log.warn("Exception", ex); //$NON-NLS-1$
                    useSleep = true;
                }
            }

            if (useSleep)
            {
                // create a listener // TODO avoid the expense of creation and registration
                ScriptConduit listener = new ScriptConduit()
                {
                    public boolean addScript(String script)
                    {
                        try
                        {
                            synchronized (scriptSession.getScriptLock())
                            {
                                scriptSession.getScriptLock().notifyAll();
                            }
                        }
                        catch (Exception ex)
                        {
                            log.warn("Failed to notify all ScriptSession users", ex); //$NON-NLS-1$
                        }

                        // just listening!
                        return false;
                    }

                    public void flush()
                    {
                    }
                };
                scriptSession.addScriptConduit(listener);

                // The comet part of a poll request
                try
                {
                    scriptSession.getScriptLock().wait(sleepTime);
                }
                catch (InterruptedException ex)
                {
                    log.warn("Interupted", ex); //$NON-NLS-1$
                }
                finally
                {
                    scriptSession.removeScriptConduit(listener);
                }
            }
        }
    }

不过目前我还没有搞清楚这些代码是起什么作用的。
0 请登录后投票
   发表时间:2006-12-27  
常常有Javaeyer通过短信问我要CometServer的源代码,特发一个附件在此
0 请登录后投票
   发表时间:2006-12-27  
基于 NIO 的web server 能够有效的解决线程分配的问题.

但由于是长连接, 客户端数量越来越多时候,仍然难以解决负载问题.

http://www.iteye.com/topic/39063
0 请登录后投票
   发表时间:2007-01-06  
我測試了DWR 2.0的reverse ajax
發現他還是client poll

請問要如何使用DWR 2.0 reverse ajax的comet ?
0 请登录后投票
   发表时间:2007-01-06  
我測試了DWR 2.0的reverse ajax
發現他還是client poll

請問要如何使用DWR 2.0 reverse ajax的comet ?
0 请登录后投票
   发表时间:2007-01-07  
普通的符合servlet规范的web容器,并不支持真正的comet服务。因此,我怀疑dwr2.0的reverse ajax只能通过client poll来模拟comet 连接。
0 请登录后投票
   发表时间:2007-01-09  
写了一些关于Comet技术的介绍,有兴趣的分享一起一下:
Comet技术介绍
0 请登录后投票
   发表时间:2007-01-22  
通过一个iframe连接到服务器上,服务器在需要的时机发送js代码,iframe收到代码的时候,会即时执行。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics