webapi 很久没访问 访问超时 - CSDN
精华内容
参与话题
  • 最近做一个项目遇到首次加载...原理是:由于web代理默认是开启的,也就是HttpWebRequest.DefaultWebProxy的值不为null,而这个DefaultWebProxy是一个全局变量。故第一次调用webservice方法的时候只有等这个默认

    最近做一个项目遇到首次加载webservice的时候特别慢,于是Google一番,得到结果是

    <system.net>
        <defaultProxy enabled="false" useDefaultCredentials="false">
          <proxy/>
          <bypasslist/>
          <module/>
        </defaultProxy>
      </system.net>

    原理是:由于web代理默认是开启的,也就是HttpWebRequest.DefaultWebProxy的值不为null,而这个DefaultWebProxy是一个全局变量。故第一次调用webservice方法的时候只有等这个默认代理超时以后才能绕过,所以第一次比较慢。


    然而这个方法还不是特别慢的最大原因,所以即使这么做了效果依然没有明显的变快,于是又是一番的Google。

    最终发现一个另一个因素:

            原因很简单,就是因为在第一次连接Webservice时,应用程序动态编译生成序列化程序集导致的慢。

    微软官方的说明:

            https://support.microsoft.com/zh-cn/kb/872800


    问题知道了那么就说说如何解决:

    1、首先如何提前生成序列化程序集


    这个时候你会发现你的bin目录下回生成一个“***.XmlSerializers.dll” 


    2、接下来就简单了,在程序启动的时候就把这个文件加载进来就OK了

      Assembly.LoadFrom(Application.StartupPath + "\\***.XmlSerializers.dll");


            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                bool ok;
                var m = new System.Threading.Mutex(true, "***.exe", out ok);
                if (!ok) return;
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Assembly.LoadFrom(Application.StartupPath + "\\***.XmlSerializers.dll");
                Application.Run(new FormMain());
                GC.KeepAlive(m);
            }


    3、骚年启动你的应用程序吧



    展开全文
  • 2019独角兽企业重金招聘Python工程师标准>>> ...

        在项目中会遇到这样的情况,由于后台需要执行、计算一段时间(如计算积分、自动排课等)。这时前台请求一段时间后,得不到返回结果就会发生请求超时。

        拿自动排课来说,如果一个学校上百个班级,执行一次排课可能需要1-2分钟甚至更长时间,那么会造成前台访问接口超时(当然也可以延长超时时间实现)。

    解决方案:

        考虑改造为轮询查询程序执行结果。

        1. 后台改造:

            将自动排课功能的接口分为两个:

                ①创建线程执行自动排课

                ②提供接口查询排课结果

            对原有的方法进行改造:原有的方法,方法执行完成后才会返回执行结果。时间过长,考虑将原方法改造为线程执行,这样一旦线程开始执行,就可以返回结果。

     

            改造方法:

    • 自动排课功能所在的service类实现Runnable接口,将自动排课的实现逻辑写在run方法中。
    • 编写方法①创建并执行线程,执行run方法。
    • Controller层调用方法①实现自动排课功能。
    • 对于自动排课结果,可以放在redis中,接口①实时更新自动排课的状态(成功或者失败),可以通过接口②每间隔一段时间查询自动排课的结果。

            

            代码示例:

    Controller层

    
    @Controller
    public class Controller{
    
        @Autowired
        //自动注入排课功能所在的service
        private CourseTableService courseTableService; 
    
        @RequestMapping(value = "/arrange/{id}")
        @ResponseBody
        public ResponseMessage arrange(@PathVariable String id) {
            return courseTableService.arrange(id); //自动排课
        }
    
        @RequestMapping(value = "/arrangeResult/{id}")
        @ResponseBody
        public Map<String,Object> arrangeResult(@PathVariable String id) {
            //查询自动排课结果,并返回
        }
    }

    Service层

    @Service
    @Transactional(readOnly = true)
    public class CourseTableService implements Runnable {  //实现Runnable接口
        @Autowired
        private ThreadPoolTaskExecutor taskExecutor; //线程池  
     
        //自动paike
        public ResponseMessage arrange(String scheduleId) {
            this.scheduleId=scheduleId;  //设置run方法中需要用的参数
            taskExecutor.execute(this); //执行线程
            return ResponseMessage.ok(); //返回线程执行结果
        }
     
        //自动排课,线程
        public void run(){ 
            //排课逻辑代码
            String scheId=this.scheduleId; //使用接收的参数
        }
    }

     

        2. 前端大致分两次请求后台接口:

        第一次请求接口自动排课(线程或者mQ执行),这样在启动自动排课的时候就返回请求结果,告知用户正在进行排课。

        然后轮询调用第二接口,每隔几秒钟就去查询排课的结果。如果返回的状态为0代表排课成功,提示用户;如果返回的状态为1达标排课失败,提示失败原因;如果返回的状态为2代表排课正在执行中,继续轮询访问查询排课结果的接口。

        主要代码示例:

    var intervalFlag=true; //是否执行轮询的标志
    //_post2是封装的ajax请求,                
    $._post2('/arrange/' + _id, {}, function(res) { 
        var interVal;
        //调用接口,查询自动排课结果,加上这个是为了用户点击后立马访问,ajax同步访问,
        //因为这次的查询结果决定了,是否执行轮询。
        getProgress(_id, interVal); 
        if(intervalFlag){
            //第一次查询结果表明排课还在进行中,才会执行轮询。
            //如果第一次已经返回结果表示程序执行完成,就不需要轮询访问排课结果了。
            interval(_id); 
        }
    });
    
    // 进度查询
    function getProgress(_id, interVal) {
        $._post2('/arrangeResult/' + _id, {}, function(res) {
            if (res.arrangeStatus == 0) {
                //排课成功
                clearInterval(interVal); //清空轮询
                intervalFlag=false; //设置为不执行轮询
            }else if(res.arrangeStatus==1){
                //排课失败
                clearInterval(interVal);
                intervalFlag=false;
            }else if(res.arrangeStatus==2){
                //排课进行中,什么都不做
            }
       });
    }
    
    // 隔两秒访问
    function interval(_id) {
        var pro;
        // 定时器
        var interVal;
        interVal = setInterval(function() {
            // 获取返回对象
            pro = getProgress(_id, interVal);
        }, 2000);
    }

     

    转载于:https://my.oschina.net/u/3706132/blog/1550617

    展开全文
  • 反向Ajax,第3部分:Web服务器和Socket.IO 作者:Mathieu Carbou 译言 时间:2011-10...摘要:英文原文:Reverse Ajax, Part 3: Web servers and Socket.IO 前言 时至今日,用户期待的是可通过web访问快速、动态的应

    反向Ajax,第3部分:Web服务器和Socket.IO

    作者:Mathieu Carbou  译言  时间:2011-10-18  阅读:2319 次  原文链接  [收藏]  

    小提示:点击可切换浏览

    摘要:英文原文:Reverse Ajax, Part 3: Web servers and Socket.IO 前言 时至今日,用户期待的是可通过web访问快速、动态的应用。这一文章系列展示了如何使用反向......

      英文原文:Reverse Ajax, Part 3: Web servers and Socket.IO
      前言

      时至今日,用户期待的是可通过web访问快速、动态的应用。这一文章系列展示了如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用。系列的第1部分介绍了反向Ajax、轮询(polling)、流(streaming)、Comet和长轮询(long polling)。你已经了解了Comet是如何使用HTTP长轮询的,这是可靠地实现反向Ajax的最好方式,因为现有的所有浏览器都提供支持。系列的第2部分说明了如何使用WebSocket来实现反向Ajax,一些代码例子被用来帮助说明WebSocket、FlashSocket、服务器端的约束、请求作用域(request-scoped)服务以及暂停长生存期请求等。

      在本篇文章中,我们深入细节,讨论在web应用中使用不同web容器和API(Servlet 3.0和Jetty Continuations)的Comet和WebSocket,了解如何通过使用诸如Socket.IO一类的抽象库来透明地使用Comet和Websocket。Socket.IO使用功能检测来确定连接是使用WebSocket、Ajax长轮询、Flash还是其他方式来建立。

      前提条件

      理想情况下,要充分体会本文的话,你应该对JavaScrpit和Java有一定的了解。本文中创建的例子是使用Google Guice来构建的,这是一个使用Java编写的依赖注入框架。若要读懂文中所谈内容,你应该要熟悉诸如Guice、Spring或是Pico一类的依赖注入框架的概念。

      若要运行本文中的例子,你还需要最新版本的Maven和JDK(参见参考资料)。

      Comet和WebSocket的服务器端解决方案

      你在第1部分内容中已经了解到了,Comet(长轮询或是流)需要服务器端能够暂停某个请求,并在一个可能的长延迟之后恢复或是完成该请求。第2部分内容描述了服务器端如何使用非阻塞式的I/O功能来处理大量的连接,以及它们只能使用线程来服务请求(每个请求一个线程模式)。你也已经了解到了WebSocket的使用是服务器端依赖的,且并非所有的服务器都支持WebSocket。

      本节内容说明了如果适用的话,那么在Jetty、Tomcat和Grizzly等web服务器上是如何使用Comet和WebSocket的。本文提供的源代码包含了Jetty和Tomcat的一个聊天web应用例子。本节内容还讨论了下面的这些应用服务器:Jboss、Glassfish和WebSphere所支持的API。

      Jetty

      Jetty是一个web服务器,支持Java Servlet 3.0规范、WebSocket和其他的许多集成规范。Jetty:

      1. 功能强大且灵活

      2. 易于嵌入

      3. 支持虚拟主机、会话集群和许多可很容易地通过用于Google App Engine的托管服务的Java代码或是XML来配置的功能。

      核心的Jetty项目由Eclipse Foundation打理。

      从版本6开始,Jetty加入了一个被称作Jetty Continuation(Jetty延续)的异步API,该API允许请求被暂停并在之后被恢复。表1给出了所支持的规范和Jetty的主要版本系列的API之间的一个对照关系。

      表1. Jetty的版本和支持

    Supports Jetty 6 Jetty 7 Jetty 8
    Non-blocking I/O X X X
    Servlet 2.5 X X X
    Servlet 3.0   X X
    Jetty Continuations (Comet) X X X
    WebSockets   X X

      若要实现使用Comet的反向Ajax的话,你可以使用Jetty的Continuation API,如清单1所示:

      清单1. 用于Comet的Jetty Continuation API

    // 暂停一个来自servlet方法(get、post......)的请求:
    protected
    void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
    Continuation continuation
    = ContinuationSupport.getContinuation(req);
    // 可选的做法,设置超时以避免请求挂起过久
    continuation.setTimeout(0);
    // 挂起请求
    continuation.suspend();
    // 保存引用,以备将来另一线程使用
    continuations.offer(continuation);
    }
    // 然后,来自另一个想给客户发送事件的线程:
    while (!continuations.isEmpty()) {
    Continuation continuation
    = continuations.poll();
    HttpServletResponse response
    =
    (HttpServletResponse) continuation.getServletResponse();
    // 向响应中写入
    continuation.complete();
    }

      完整的web应用在本文所带的源代码中。Jetty Continuation被打包放在一个JAR归档文件中,你需要把这一JAR文件放在web应用的WEB-INF/lib目录下才能使用Jetty的Comet功能。Jetty Continuation在Jetty 6、7和8上都是可用的。

      从Jetty 7开始,你还可以访问WebSocket功能,把Jetty的WebSocket JAR文件放在web应用的WEB-INF/lib目录下以获得对Jetty的WebSocket API的访问,如清单2所示:

      清单2. Jetty的Websocket API

    // 实现doWebSocketConnect并返回WebSocket的实现

    publicfinalclass ReverseAjaxServletextends WebSocketServlet {
    @Override
    protected WebSocket doWebSocketConnect(HttpServletRequest request,
    String protocol) {
    return [...]
    }
    }

    // WebSocket的示例实现

    class Endpointimplements WebSocket {
    Outbound outbound;
    publicvoid onConnect(Outbound outbound) {
    this.outbound= outbound;
    }
    publicvoid onMessage(byte opcode, String data) {
    outbound.sendMessage(
    "Echo:"+ data);
    if("close".equals(data))
    outbound.disconnect();
    }
    publicvoid onFragment(boolean more,byte opcode,
    byte[] data,int offset,int length) {
    }
    publicvoid onMessage(byte opcode,byte[] data,
    int offset,int length) {
    onMessage(opcode,
    new String(data, offset, length));
    }
    publicvoid onDisconnect() {
    outbound
    =null;
    }
    }

      在下载的源代码的jetty-websocket目录下有一个聊天应用的例子,该例子说明了如何使用Jetty的WebSocket API。

      Tomcat

      Tomcat可能是最广为人知的web服务器了,其已经使用多年,且被作为web容器整合在Jboss应用服务器的早期版本中。Tomcat也被用作是servlet规范的参考实现,但到了servlet API 2.5后就不再是了,这时人们开始寻求另一种基于非阻塞式I/O的做法(比如说Jetty)。表2给出了所支持的规范和两个最新的Tomcat版本系列的API之间的对照。

      表2. Tomcat的支持

    Supports Tomcat 6 Tomcat 7
    Non-blocking I/O X X
    Servlet 2.5 X X
    Servlet 3.0   X
    Advanced I/O (Comet) X X
    WebSockets    

      正如表2所示的那样,Tomcat不支持WebSocket;它有一个相当于Jetty的Continuation的API,这一被称为Advanced I/O的API支持Comet。与其说Advanced I/O是一个很好地方便了Comet使用的API,倒不如说它是一个封装了NIO的低层面包装器。它缺乏文档资料,几乎没有什么使用API的应用例子。清单3给出了一个servlet例子,该例子挂起并恢复聊天web应用中的请求。你可以在本文的源代码中找到完整的web应用。

      清单3. Tomcat用于Comet的API

    publicfinalclass ChatServletextends HttpServlet
    implements CometProcessor {
    privatefinal BlockingQueue events=
    new LinkedBlockingQueue();

    publicvoid event(CometEvent evt)
    throws IOException, ServletException {
    HttpServletRequest request
    = evt.getHttpServletRequest();
    String user
    =
    (String) request.getSession().getAttribute(
    "user");
    switch (evt.getEventType()) {
    case BEGIN: {
    if ("GET".equals(request.getMethod())) {
    evt.setTimeout(Integer.MAX_VALUE);
    events.offer(evt);
    }
    else {
    String message
    = request.getParameter("message");
    if ("/disconnect".equals(message)) {
    broadcast(user
    +" disconnected");
    request.getSession().removeAttribute(
    "user");
    events.remove(evt);
    }
    elseif (message!=null) {
    broadcast(
    "["+ user+"]"+ message);
    }
    evt.close();
    }
    }
    }
    }

    void broadcast(String message)throws IOException {
    Queue q
    =new LinkedList();
    events.drainTo(q);
    while (!q.isEmpty()) {
    CometEvent event
    = q.poll();
    HttpServletResponse resp
    = event.getHttpServletResponse();
    resp.setStatus(HttpServletResponse.SC_OK);
    resp.setContentType(
    "text/html");
    resp.getWriter().write(message);
    event.close();
    }
    }
    }

      在Tomcat中,异步的servlet必须要实现CometProcessor。对于异步的servlet来说,Tomcat并不调用标准的HTTP方法(doGet、doPost等),取而代之的是,事件会被发送给event(CometEvent)方法。当请求首次到达时,例子查看是否是一个GET,是的话便挂起它,evt.close()没有被调用。如果是一个POST的话,这意味着是用户发送了一个消息,因此给其他CometEvent广播消息,然后调用evt.close()来完成该post请求。在客户这一端,广播会让所有的长轮询请求完成消息的发送,另一个长轮询请求会被立刻发送出去以接收接下来的事件。

      Grizzly和Glassfish

      Grizzly不是一个web容器,它更像是一个用来帮助开发者构建可伸缩应用的NIO框架。它是被作为Glassfish项目的一部分开发出来的,但也可以独立或是嵌入使用。Grizzly提供了充当HTTP/HTTPS服务器的组件,除了其他的一些组件之外,其还提供了Bayeux Protocol、Servlet、HttpService OSGi和Comet组件。Grizzly支持WebSocket,其被用在Glassfish中提供Comet和WebSocket支持。

      Oracle的应用服务器Glassfish是J2EE 6规范的参考实现。Glassfish是一个完整的套件,类似WebSphere和Jboss,使用Grizzly来支持NIO、Websocket和Comet。它的基于OSGI的模块化架构,使得其在更换组件时具有真正的灵活性。表3说明了Glassfish对Comet和WebSocket的支持。

      表3. Glashfish的支持

    Supports Glassfish 2 Glassfish 3
    Non-blocking I/O X X
    Servlet 2.5 X X
    Servlet 3.0   X
    Comet X X
    WebSockets   X

      Grizzly的用法值得一说,因为它原本打算是以嵌入的方式或是直接通过Java代码来使用的。它被广泛用作支持Comet和WebSocket的框架,可被嵌入到一个更大的应用中,比如说Glassfish,该应用提供了web部署功能和Servlet规范API。

      请参阅参考资料一节获得到Grizzly或是Glassfish中的WebSocket和Comet的例子的链接,因为Glassfish使用了Grizzly,所以例子在两者上面都是应该能够运行的。WebSocket API与Jetty中的非常类似,但Comet API就更复杂一些。

      Jboss

      Jboss是一个构建在Tomcat之上的应用服务器,它从版本5开始支持Comet和NIO。Jboss 7还在开发中,不过也被放在了下面的表4中进行比较。

      表4. Jboss的支持


    Supports Jboss 5 Jboss 6 Jboss 7
    Non-blocking I/O X X X
    Servlet 2.5 X X X
    Servlet 3.0   X X
    Comet X X X
    WebSockets      

      WebSphere

      WebSphere是一个IBM的应用服务器,版本8的WebSphere支持Servlet 3 API(包含了用于Comet的标准的异步API)(请参阅参考资料来了解发布公告的内容)。

      表5. WebSphere的支持  

    Supports WebSphere 8
    Non-blocking I/O X
    Servlet 2.5 X
    Servlet 3.0 X
    Comet X
    WebSockets  

      通用API方面的情况

      每个服务器都有自己的本地Comet和WebSocket API,正如你或已猜到的那样,编写一个可移植的web应用可能会很难。Servlet 3.0包含了挂起和之后再恢复请求的附加方法,允许所有支持Servlet 3.0规范的web容器支持Comet和长轮询请求。

      Jetty提供了一个被称作Jetty Continuation的库,该库独立于Jetty容器存在。Jetty Continuation库非常聪明,能够检测出可用的容器或是规范。如果是运行在Jetty服务器上,应用所使用的就是本地的Jetty API;如果是运行在支持Servlet 3.0规范的容器上的话,应用所使用的就是这一通用的API;否则的话,就要使用一个无伸缩性的实现。

      关于WebSocket,现在在Java中还没有一个标准,因此,如果你想要使用WebSocket的话,就需要在web应用中使用容器供应商的API。

      表6总结了各种服务器支持的技术。

      表6. 服务器支持的技术

    Container Comet WebSocket
    Jetty 6 Jetty Continuations N/A
    Jetty 7 Servlet 3.0
    Jetty Continuations
    Native Jetty API
    Jetty 8 Servlet 3.0
    Jetty Continuations
    Native Jetty API
    Tomcat 6 Advanced I/O N/A
    Tomcat 7 Servlet 3.0
    Advanced I/O
    Jetty Continuations
    N/A
    Glassfish 2 Native Grizzly API N/A
    Glassfish 3 Servlet 3.0
    Native Grizzly API
    Jetty Continuations
    Native Grizzly API
    Jboss 5 Native Jboss API N/A
    Jboss 6 Servlet 3.0
    Native Jboss API
    Jetty Continuations
    N/A
    Jboss 7 Servlet 3.0
    Native Jboss API
    Jetty Continuations
    N/A
    WebSphere 8 Servlet 3.0
    Jetty Continuations
    N/A

      除了使用容器的API之外,在WebSocket方面显然还没有什么解决方案。至于Comet,每个支持Servlet 3.0规范的容器都支持Comet。Jetty Continuation在这方面的优势是在所有的这些容器上都提供了对Comet的支持,因此,某些反向Ajax库(这在下一节内容和本系列的下一篇文章中会谈到)使用Jetty Continuation来作为它们的服务器端API。

      Jetty Continuation API在本文的Jetty例子中有说明,Servlet 3.0规范已经在本系列第1部分的两个Comet例子中用到并做了介绍。

      抽象库

      考虑一下所有主要的API(Servlet 3.0和Jetty Continuation),加上服务器端的所有本地化支持,以及客户端的两种主要的实现反向Ajax的方式(Comet和WebSocket),通过编写自己的JavaScript和Java代码来捆绑它们实属不易,你还要考虑超时、连接失败、确认、排序、缓冲等等。

      本文余下部分的内容说明了Socket.IO的用途,本系列的第4部分内容则会探讨Atmosphere和CometD,这三个库都是开源的,它们在许多服务器上都支持Comet和WebSocket。

      Socket.IO

      Socket.IO是一个JavaScript客户端库,类似于WebSocket,其提供了单个的API来连接远程服务器,异步地发送和接收消息。通过提供一个通用的API,Socket.IO支持如下多种传输:WebSocket、Flash Socket、长轮询、流、永久Iframe和JSONP轮询。Socket.IO检测浏览器的功能,然后尝试选择可用的最好传输方式。Socket.IO库几乎兼容所有的浏览器(包括较旧的那些,比如IE 5.5)和移动浏览器,它还拥有其他的一些功能,比如说心跳、超时、断开连接和错误处理等。

      Socket.IO网站(参见参考资料)详细描述了该库的使用方式,以及其所用到的浏览器和反向Ajax技术。基本情况是这样,Socket.IO用到了一个通信协议,该协议使得客户端的库能够与服务器端的端点进行通信,服务器端的端点能够理解Socket.IO协议。Socket.IO一开始是为Node JS这一用来构建更快的服务器的JavaScript引擎开发的,许多项目带来了对其他语言的支持,其中就包括了Java语言。

      清单4给出了一个在客户端使用Socket.IO JavaScript库的例子,Socket.IO网站上有文档和例子。

      清单4. Socket.IO客户端库的用法

    var socket = new io.Socket(document.domain, {
    resource:
    'chat'
    });
    socket.on(
    'connect', function() {
    // Socket.IO已连接
    });
    socket.on(
    'disconnect', function(disconnectReason, errorMessage) {
    // Socket.IO已断开连接
    });
    socket.on(
    'message', function(mtype, data, error) {
    // 服务器发送一个事件
    });

    // 现在处理程序已经定义好了,可以建立连接:
    socket.connect();

      若要使用Socket.IO JavaScript库的话,你需要有相应的被称作Socket.IO Java(参见参考资料)的Java部分。这一项目最初是由Apach Wave团队启动的,是为了给Wave提供反向Ajax支持,这是在WebSocket可用之前的事。Socket.IO Java派生出来后由Ovea(一家专门从事事件驱动的web开发的公司)来维护,再后来就被弃之不顾了。由于有多种传输的缘故,开发支持Socket.IO客户端库的后端是很复杂的过程。本系列的第4部分内容会说明,为了获得更好的伸缩性和浏览器支持,在客户端库中支持多种传输是没有必要的,因为有长轮询和WebSocket就足够了。在WebSocket不可用时,Socket.IO确实是一个不错的选择。

      Socket.IO Java使用Jetty Continuation API来挂起和恢复请求,其使用本地的Jetty WebSocket API作为WebSocket支持。你可以确定使用了Socket.IO Java的web应用可在哪个服务器上正确地运行。

      下面清单5中的例子说明了在服务器端如何使用Socket.IO,你需要定义一个继承了SocketIOServlet的servlet,并实现一个返回某种端点表示的方法。这一API非常类似于WebSocket API,它的优点是用在服务器端,独立于客户端所选择的传输方式。Socket.IO把所有的传输类型都转换成服务器端的同一API。

      清单5. 聊天例子中的Socket.IO Java的使用——servlet

    public final class ChatServletextends SocketIOServlet {
    private final BlockingQueue endpoints=
    new LinkedBlockingQueue();

    @Override
    protected SocketIOInbound doSocketIOConnect
    (HttpServletRequest request) {
    String user
    =
    (String) request.getSession().getAttribute(
    "user");
    return user== null?null :new Endpoint(this, user, request);
    }

    void broadcast(String data) {
    for (Endpoint endpoint : endpoints) {
    endpoint.send(data);
    }
    }

    void add(Endpoint endpoint) {
    endpoints.offer(endpoint);
    }

    void remove(Endpoint endpoint) {
    endpoints.remove(endpoint);
    }
    }
      

      清单6说明了返回端点的方式。

      清单6. 聊天例子中的Socket.IO Java库的用法——endpoint

    class Endpointimplements SocketIOInbound {
    [...]
    private SocketIOOutbound outbound;
    [...]

    @Override
    publicvoid onConnect(SocketIOOutbound outbound) {
    this.outbound= outbound;
    servlet.add(
    this);
    servlet.broadcast(user
    +" connected");
    }

    @Override
    publicvoid onDisconnect(DisconnectReason reason,
    String errorMessage) {
    outbound
    = null;
    request.getSession().removeAttribute(
    "user");
    servlet.remove(
    this);
    servlet.broadcast(user
    +" disconnected");
    }

    @Override
    public void onMessage(int messageType, String message) {
    if ("/disconnect".equals(message)) {
    outbound.close();
    }
    else {
    servlet.broadcast(
    "["+ user+"]"+ message);
    }
    }

    void send(String data) {
    try {
    if (outbound!=null
    && outbound.getConnectionState()== ConnectionState.CONNECTED) {
    outbound.sendMessage(data);
    }
    }
    catch (IOException e) {
    outbound.close();
    }
    }

    }

      Socket.IO的完整例子放在源代码的socketio目录下。

      结束语

      所有的web容器都支持Comet,且大部分的容器都支持WebSocket,即使规范带来了几种不同的本地化实现,你还是可以使用Comet和通用API(Servlet 3.0和Jetty Continuation)来开发web应用。且更乐观的情况是,你可以使用诸如Socket.IO一类的库,以透明的方式来利用Comet和WebSocket的强大功能。还有两个库,Atmosphere和CometD,会在本系列的下一篇文章中谈及。这三个库提供了多浏览器支持、非常出色的用户体验,以及错误处理、更简单的API、超时和重连接等多方面的好处。

      下载

      描述        名称           大小   下载方法

      文章的源代码    reverse_ajaxpt3_source.zip   21KB     HTTP

      学习资料

      1. 阅读这一系列之前的部分:

        1.1. 第1部分:Comet介绍

        1.2. 第2部分:Websocket

      2. JSR 315:Java Servlet 3.0规范是2.5规范的更新。

      3. 阅读IBM WebSphere Application Server V8.0的发布公告

      4. “Google AppEngine uses Jetty!”介绍了Google的Jetty定制。

      5. 了解更多关于Jetty Continuation的功能。

      6. 了解一个使用Grizzly的Glassfish WebSocket例子。

      7. WebSphere Application Server:了解更多关于IBM WebSphere系列中的这一旗舰产品。

      8. WebSphere 8(支持Comet)启用了智能化的应用环境管理,有助于更快地提交丰富的用户体验。

      9. Socket.IO的目标是使实时应用在每种浏览器和移动设备上都成为可能,其减轻了不同传输机制之间的区别。

      10. “Start using HTML5 WebSockets today”(Nettuts+):重温在PHP中如何运行一个WebSocket服务器,并考虑如何构建一个客户端来通过WebSocket协议发送和接收消息。

      11. “The WebSocket API”(W3C, July 2011):这一规范定义的API使得网页能够使用WebSocket协议来和远程主机进行双向通信。

      12. 了解更多关于Servlet 3.0对异步处理的支持方面的内容。

      13. Philip McCarthy的博客上的文章Comet & Java: Threaded Vs Nonblocking I/O中有着更多的内容。

      14. 在维基百科上了解这些内容:

        14.1. Ajax
        14.2. Reverse Ajax
        14.3 WebSockets

      15. “Exploring Reverse AJAX”:获得一些关于反向Ajax技术的介绍说明。

      16. “Cross-domain communications with JSONP, Part 1: Combine JSONP and jQuery to quickly build powerful mashups”(developerWorks, February 2009):了解如何把不起眼的跨域调用技术(JSONP)和一个灵活的JavaScript库(JQuery)结合在一起,以令人惊讶的速度构建出一些功能强大的聚合应用。

      17. “Build Ajax applications with Ext JS”(developerWorks, July 2008):对Ext Js背后的面向对象JavaScript 设计概念做了一个概述,并说明了如何把Ext JS框架用作富互联网应用的UI元素。

      18. “Compare JavaScript frameworks”(developerWorks, February 2010):对极大地增强了JavaScript开发的那些框架有一个整体的了解。

      19. “Mastering Ajax, Part 2: Make asynchronous requests with JavaScript and Ajax”(developerWorks, January 2006):学习如何使用Ajax和XMLHttpRequest对象来创建一种永不会让用户等待服务器响应的请求/响应模型。

      20. “Create Ajax applications for the mobile Web”(developerWorks, March 2010):了解如何使用Ajax构建跨浏览器的智能手机Web应用。

      21. “Where and when to use Ajax in your applications”(developerWorks, February 2008):了解如何使用Ajax来改进网站,同时避免糟糕的用户体验。

      22. “Improve the performance of Web 2.0 applications“(developerWorks, December 2009):探讨不同的浏览器端缓存机制。

      23. “Introducing JSON”(JSON.org):获得对JSON语法的一个入门介绍。

      24. developerWorks Web development zone:获得各种谈论基于Web的解决方案的文章。

      25. developerWorks podcasts:收听各种与软件开发者进行的有趣的访谈和讨论。

      26. developerWorks technical events and webcasts:随时关注developerWorks的技术事件和webcast的进展。

      获取产品和技术

      1. Jetty:获取Jetty,一个web服务器和javax.servlet容器,外带对WebSocket的支持。

      2. Apache Tomcat Advanced I/O文档:获得有用的链接、用户指南、参考手册和Apache Tomcat开发说明。

      3. Grizzly NIO Framework:帮助你使用Java NIO API。

      4. Grizzly Comet例子:在从头开始构建一个新的应用之前,了解需要对现有应用做哪些修改。

      5. Glassfish Application Server:获得主要的Glassfish Server的开源版本。

      6. Socket.IO Java:获得原始的项目和最后更新的Ovea的派生版本。

      7. Apache Maven:获取Maven,一个软件项目管理和包容工具。

      8. Java Development Kit, Version 6:获得Java平台标准版(Java Platform, Standard Edition,Java SE),该平台允许你在台式机和服务器上,以及在当今要求苛刻的嵌入式环境上开发和部署Java应用。

      9. 免费试用IBM软件,下载使用版,登录在线试用,在沙箱环境中使用产品,或是通过云来访问,有超过100种IBM产品试用版选择。

      讨论

      1. 参加论坛的讨论

      2. 现在就创建你的developerWorks个人资料,并设置一个关于Reverse Ajax的观看列表。与developerWorks社区建立联系并保持联系。

      3. 找到其他在web开发方面感兴趣的developerWorks成员

      4. 分享你的知识:加入一个关注web专题的developerWorks组

      5. Roland Barcia在他的博客中谈论Web 2.0和中间件

      6. 关注developerWork成员的shared bookmarks on web topics

      7. 快速获得答案:访问Web 2.0 Apps论坛

      8. 快速获得答案:访问Ajax论坛

      关于作者

      Mathieu Carbou是Ovea的一位提供服务和开发解决方案的Java web架构师和顾问。他是几个开源项目的提交者和领导者,也是Montreal的Java User Group的一位演讲者和领导者。Mathieu有着很强的代码设计和最佳实践背景,他是一个从客户端到后端的事件驱动的web开发方面的专家。他的工作重点是在高度可伸缩的web应用中提供事件驱动的和消息式的解决方案。你可以看一看他的博客

    展开全文
  • OkHttp超时时间设置

    万次阅读 2019-01-08 11:05:48
    OkHttp3中设置超时的方法 public WebApi(){ client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) ...

     

    OkHttp3中设置超时的方法

        public WebApi(){
            client = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(20, TimeUnit.SECONDS)
                    .build();
        }
    

     

    捕获OkHttp3超时

    然后捕获异常,加以处理。

     

        public void GetServersList(IServersListEvent serversListEvent) {
            this.serversListEvent = serversListEvent;
            serversLoadTimes = 0;
            Request request = new Request.Builder()
                    .url(serversListUrl)
                    .build();
            client.newCall(request).enqueue(new Callback() {
     
                @Override
                public void onFailure(Call call, IOException e) {
                    if(e.getCause().equals(SocketTimeoutException.class) && serversLoadTimes<maxLoadTimes)//如果超时并未超过指定次数,则重新连接
                    {
                        serversLoadTimes++;
                        client.newCall(call.request()).enqueue(this);
                    }else {
                        e.printStackTrace();
                        WebApi.this.serversListEvent.getServers(null);
                    }
                }
     
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String html = new String(response.body().bytes(), "big5");
                    Matcher m = serversListPattern.matcher(html);
                    ServersList serverList = new ServersList();
                    while (m.find()){
                        serverList.add(new ServerInfo(m.group(1), m.group(2)));
                    }
     
                    Matcher mc1 = selectServerCodePattern.matcher(html);
                    Matcher mc2 = selectCityCodePattern.matcher(html);
                    if(mc1.find())
                        serverList.selectServerCode=mc1.group(1);
                    if(mc2.find())
                        serverList.selectCityCode=mc2.group(1);
     
                    WebApi.this.serversListEvent.getServers(serverList);
                }
            });
        }
    

     

    解析dns超时时间

    问题
    使用OkHttp,设备切换路由后,访问网络出现长时间无响应,很久以后才抛出UnknownHostException,这明显不是我们想要的,我们设置的connectTimeout属性似乎对dns的解析不起作用。

    如何解决
    我们先看看OkHttpClient有没有关于Dns的相关设置,发现OkHttpClient的Builder类存在dns()方法可以设置一个Dns类型参数。
    Dns类源码如下:

    package okhttp3;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * A domain name service that resolves IP addresses for host names. Most applications will use the
     * {@linkplain #SYSTEM system DNS service}, which is the default. Some applications may provide
     * their own implementation to use a different DNS server, to prefer IPv6 addresses, to prefer IPv4
     * addresses, or to force a specific known IP address.
     *
     * <p>Implementations of this interface must be safe for concurrent use.
     */
    public interface Dns {
      /**
       * A DNS that uses {@link InetAddress#getAllByName} to ask the underlying operating system to
       * lookup IP addresses. Most custom {@link Dns} implementations should delegate to this instance.
       */
      Dns SYSTEM = new Dns() {
        @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException {
          if (hostname == null) throw new UnknownHostException("hostname == null");
          try {
            return Arrays.asList(InetAddress.getAllByName(hostname));
          } catch (NullPointerException e) {
            UnknownHostException unknownHostException =
                new UnknownHostException("Broken system behaviour for dns lookup of " + hostname);
            unknownHostException.initCause(e);
            throw unknownHostException;
          }
        }
      };
    
      /**
       * Returns the IP addresses of {@code hostname}, in the order they will be attempted by OkHttp. If
       * a connection to an address fails, OkHttp will retry the connection with the next address until
       * either a connection is made, the set of IP addresses is exhausted, or a limit is exceeded.
       */
      List<InetAddress> lookup(String hostname) throws UnknownHostException;
    }


     
    这是一个抽象类,并且其中已经写好了默认实现并赋值给了SYSTEM对象。
    透过代码我们可以看出,解析dns主要是靠这行代码:

    InetAddress.getAllByName(hostname)


    Ok,我们已经知道如何解析dns并设置给OkHttpClient了,现在我们只需要重新实现这个过程,插入超时控制,并让OKHttp调用新的Dns解析就好了。

    实现
    实现抽象类Dns

    package com.x.http;
    
    import okhttp3.Dns;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.util.Arrays;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.TimeUnit;
    
    public class XDns implements Dns {
        private long timeout;
    
        public XDns(long timeout) {
            this.timeout = timeout;
        }
    
        @Override
        public List<InetAddress> lookup(final String hostname) throws UnknownHostException {
            if (hostname == null) {
                throw new UnknownHostException("hostname == null");
            } else {
                try {
                    FutureTask<List<InetAddress>> task = new FutureTask<>(
                            new Callable<List<InetAddress>>() {
                                @Override
                                public List<InetAddress> call() throws Exception {
                                    return Arrays.asList(InetAddress.getAllByName(hostname));
                                }
                            });
                    new Thread(task).start();
                    return task.get(timeout, TimeUnit.MILLISECONDS);
                } catch (Exception var4) {
                    UnknownHostException unknownHostException =
                            new UnknownHostException("Broken system behaviour for dns lookup of " + hostname);
                    unknownHostException.initCause(var4);
                    throw unknownHostException;
                }
            }
        }
    }


     
    上面的实现主要依赖了FutureTask可以设置任务执行时间的特性,不明白的同学可以自行学习一下。
    然后把新的dns解析类设置给OkHttpClient

       

    public static OkHttpClient createClient(long timeout, long writeTimeout,
         long readTimeout, boolean bRetry) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .connectTimeout(timeout, TimeUnit.MILLISECONDS)
                    .dns(new XDns(timeout))
                    .retryOnConnectionFailure(bRetry);
            if (writeTimeout > 0)
                builder.writeTimeout(writeTimeout, TimeUnit.MILLISECONDS);
            if (readTimeout > 0)
                builder.readTimeout(readTimeout, TimeUnit.MILLISECONDS);
            OkHttpClient client = builder.build();
            client.dispatcher().setMaxRequestsPerHost(10);
            client.dispatcher().setMaxRequests(30);
            return client;
        }


    --------------------- 
    作者:猿小二 
    来源:CSDN 
    原文:https://blog.csdn.net/quwei3930921/article/details/85336552 
    版权声明:本文为博主原创文章,转载请附上博文链接!

     

     

     

     new Thread(task).start();

     这个地方应该改用线程池,DNS解析应该是比较频繁的操作,直接开新线程不合适

    展开全文
  • 时至今日,用户期待的是可通过web访问快速、动态的应用。这一文章系列展示了如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用。系列的第1部分介绍了反向Ajax、轮询(polling)、流(streaming)、Comet...
  • 又是很久没写博客了,最近一段时间换了新工作,比较忙,所以没有抽出来太多的时间写给关注我的粉丝写一些干货了,就有人问我怎么最近没有更新博客了,在这里给大家抱歉。 那么,在本篇文章中,我们就一起来探讨一下...
  • HAproxy负载均衡-ACL篇(转)

    万次阅读 2015-11-24 17:25:01
    ACL定制法则:  开放策略:拒绝所有,只开放已知  拒绝策略:允许所有,只拒绝某些 事实上实现安全策略,无非也就是以上两种方法   ...如果符合某种特定条件,则返回某种新的前缀
  • 分布式服务Dubbo:服务降级

    千次阅读 2017-12-29 11:22:12
    何为服务降级?为什么使用服务降级?...就是蝴蝶效应,当一个请求发生超时,一致等等待着服务响应,那么在高并发情况下,多请求都是因为这样一直等着响应,直到服务资源耗尽产生宕机,而宕机之后会产生导致
  • HTTP协议分析

    万次阅读 多人点赞 2019-06-23 12:30:24
    HTTP(HyperText Transfer Protocol)即超文本传输协议,是一种详细规定了浏览器和万维网服务器之间互相通信的规则,它是万维网交换信息的基础,它允许将HTML(超文本标记语言)文档从Web服务器传送到Web浏览器。...
  • Hbuilder创建app

    万次阅读 2018-01-19 17:10:03
    然而最难搞的还是真机调试,我用的小米,折腾了好久,提示联机不上,要安装手机助手。一点默认链接,果不其然,最讨厌的360流氓来了,给我pc端装手机助手,然并卵还是联不上,又让我在手机上安装手机助手,也没用,...
  • 基于 Cookie 的 SSO 中间件 kisso

    千次阅读 2016-09-19 20:24:44
    基于 Cookie 的 SSO 中间件,它是一把快速开发 java Web 登录系统(SSO)的瑞士军刀。欢迎大家使用 kisso !!  kisso 帮助文档下载 1、支持单点登录 2、支持登录Cookie缓存 3、支持防止 xss...
  • 起初程序一切正常,后来一次维护之后客户反映响应时间过长。但是当我用维护当天同样的程序再覆盖一边之后,响应时间又正常了,过一天又响应时间慢。请各位帮忙点点是哪儿的问题。谢谢!
  • 作者:【吴业亮】云计算开发工程师 博客:http://blog.csdn.net/wylfengyujiancheng一、简介 1、Haproxy是什么 ...HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行
  • WEB即时通讯/消息推送

    万次阅读 多人点赞 2017-08-15 16:15:03
    通常进行的Web开发都是由客户端主动发起的请求,然后服务器对请求做出响应并返回给客户端。但是在多情况下,你也许会希望由服务器主动对客户端发送一些数据。 那么,该如何实现这个需求,或者说该如何向网页推送...
  • 百度了好久,大部分的文章都前篇一律的说jsonp跨域,要不就是说配置CROS。看到那种文章出处应该都是一家,心好累。首先来说淘宝目前的接口是不支持jsonp请求的,配置CROS更是无稽之谈。      &...
  • Java Servlet技术

    千次阅读 2007-08-22 12:20:00
    Java Servlet技术Stephanie Bodoff当Web刚开始被用来传送服务时,服务提供者就已经意识到了动态内容的需要。Applet是为了实现这个目标的一种最早的尝试,它主要关注使用客户端平台来交付动态用户体验。与此同时,...
  • 前端开发中的地理定位问题小总结

    万次阅读 2017-03-23 16:28:17
    项目中遇到地理定位的问题,遇过不知道,遇过就发现这是个比较坑的问题。这个问题其实困扰了我挺的,还不如一次性了解清楚。所以本文进行了一些小总结,先简单总结我看过的关于定位技术的资料,然后介绍前端开发...
1 2 3 4 5 ... 20
收藏数 7,955
精华内容 3,182
热门标签
关键字:

webapi 很久没访问 访问超时