7、Comet的服務器推送技術,基於Ajax,DeferredResult實現長輪詢

注:源代碼來自享學課堂,略有修改,學習之後所做筆記,方便回顧,也給大家一個參考

DeferredResult實現長輪詢

頁面每次調用請求之後,在方法結束的時候,再次自我調用

<%@ 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>
</head>
<body>
<h1>新聞</h1>
<div>
    <div>
        <h2實時變化的新聞</h2>
        <div style="color:#F00"><b><p id="realTimeNews">  </p></b></div>
    </div>
</div>
<script type="text/javascript" src="assets/js/jquery-1.9.1.min.js"></script>
<script type="text/javascript">

    longLoop();

    function longLoop() {
        $.get("realTimeNews",function (data) {
            console.log(data);
            $("#realTimeNews").html(data);
            //馬上再發起請求
            longLoop();
        })
    }


</script>
</body>
</html>

服務器要開啓異步調用, servlet.setAsyncSupported(true);這裏的WebApplicationInitializer相當於web.xml配置修改

public class WebInit implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext)
            throws ServletException {

        AnnotationConfigWebApplicationContext ctx
                = new AnnotationConfigWebApplicationContext();
        ctx.register(CometMvcConfig.class);
        ctx.setServletContext(servletContext);
        
        ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher",
                new DispatcherServlet(ctx));
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
        //啓用異步
        servlet.setAsyncSupported(true);

    }
}

服務器基本配置

@Configuration
@EnableWebMvc
@EnableScheduling
@ComponentScan("cn.gg")
public class CometMvcConfig extends WebMvcConfigurerAdapter{

    @Bean
    public InternalResourceViewResolver viewResolver(){
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setViewClass(JstlView.class);
        return viewResolver;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/assets/**")
        		.addResourceLocations("/assets/");
    }
}

生成任意消息的對象

public class Const {
    public static final String[] NEWS = {
            "牀前明月光",
            "疑是地上霜",
            "舉頭望明月",
            "低頭思故鄉"
};
}

使用DeferredResult實現長輪詢

@Controller
@RequestMapping(produces="text/html;charset=UTF-8")
/*記得要在WebInitializer中增加servlet.setAsyncSupported(true);*/
public class PushNewsController {

    private ExecutorService executorService
            = Executors.newFixedThreadPool(1);

    @RequestMapping("/pushnews")
    public String news(){
        return "pushNews";
    }

    @RequestMapping(value="/realTimeNews")
    @ResponseBody
    /*在WebInitializer中要加上servlet.setAsyncSupported(true);*/
    public DeferredResult<String> realtimeNews(HttpServletRequest request){
        final DeferredResult<String> dr = new DeferredResult<String>();

        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int index = new Random().nextInt(Const.NEWS.length);
                //setResult會刷新頁面的數據
                dr.setResult(Const.NEWS[index]);
            }
        });
        return dr;
    }

}

訪問頁面的時候,新聞會不斷自動刷新

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章