Springmvc implements long-pulling technology
Background:
There is a communication module in the project, which was originally implemented using full-duplex websocket technology, but IE10 or lower does not support websocket, while 360 and 2345 sockets in China
The browser encapsulates all the kernels earlier than IE10. Considering the domestic customers of the website, the browser has to provide communication support when it does not support websocket.
It is decided to use the long-pulling technology in browsers that do not support websocket.
Feasibility analysis:
Servlet 3.0 has started to support async, and Spring MVC 3.2 has also begun to support Asynchronization. Therefore, we use DeferredResult to implement chat technology.
Specific implementation: 1 file Configuration:
Suppose you already have the spring + springmvc framework. We only need to make minor changes to the configuration file and declare the use of async in all filters and servlets in web. xml:
true
Complete web. xml configuration is as follows:
ContextConfigLocation
Classpath: spring-mybatis.xml
EncodingFilter
Org. springframework. web. filter. CharacterEncodingFilter
True
Encoding
UTF-8
EncodingFilter
/*
Org. springframework. web. context. ContextLoaderListener
Org. springframework. web. util. IntrospectorCleanupListener
SpringMVC
Org. springframework. web. servlet. DispatcherServlet
ContextConfigLocation
Classpath: spring-mvc.xml
1
True
SpringMVC
/
Index. jsp
File configuration.
2. Create a Controller
/*** @ Author yyp * @ file name ChatController. java * @ function to process chat messages * @ Blog http://blog.csdn.net/gisredevelopment */@ Controllerpublic class ChatController {// store all user requests private final Map
> ChatRequests = new ConcurrentHashMap
> (); // Format private final SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH: mm: ss "); /*** @ author yyp * @ login role * @ param name username * @ param session * @ return chat room page */@ RequestMapping (value = "/login ", method = RequestMethod. POST) public String login (@ RequestParam String name, HttpSession session) {session. setAttribute ("user", name); Message msg = new Message (); msg. setUser ("system"); msg. setDate (sdf. format (new Date (); msg. setContent (name + "already added"); // notify all users to enter the chat room processMessage (msg); return "room ";} /***** @ author yyp * @ function to read the latest message * @ param session * @ return DeferredResult
*/@ RequestMapping (value = "/getMessages", method = RequestMethod. GET) @ ResponseBodypublic DeferredResult
GetMessages (HttpSession session) {// retrieve the final String user = (String) session. getAttribute ("user"); // create DeferredResult
DeferredResult
Dr = new DeferredResult
(); // If the user does not exist, return directly. Otherwise, put the user into the user request list and return if (null = user) {return dr ;} else {// when DeferredResult responds to the client, remove it from the list. onCompletion (new Runnable () {@ Overridepublic void run () {// method stub automatically generated by TODO chatRequests. remove (user) ;}}); chatRequests. put (user, dr); return dr ;}/ *** @ author yyp * @ receives client messages * @ param session * @ param content * @ return Map
*/@ RequestMapping (value = "/setMessage", method = RequestMethod. POST) @ ResponseBodypublic Map
SetMessage (HttpSession session, @ RequestParam String content) {Message msg = new Message (); msg. setContent (content); msg. setDate (sdf. format (new Date (); msg. setUser (String) session. getAttribute ("user"); // publish a message to all users processMessage (msg); Map
Map = new HashMap
(1); map. put ("success", "true"); return map;}/*** @ author yyp * @ quit chat room * @ param session * @ return Map
*/@ RequestMapping (value = "/logout", method = RequestMethod. GET) @ ResponseBodypublic Map
Logout (HttpSession session) {Message msg = new Message (); String user = (String) session. getAttribute ("user"); msg. setContent ("Left"); msg. setDate (sdf. format (new Date (); msg. setUser (user); chatRequests. remove (user); // notify all users that someone has left the chat room processMessage (msg); Map
Map = new HashMap
(1); map. put ("success", "true"); return map ;} /*** @ author yyp * @ publishes Message information to all online users * @ param msg Message */private void processMessage (Message msg) {Set
Keys = chatRequests. keySet (); for (String key: keys) {chatRequests. get (key). setResult (msg );}}}
3. Create a message entity
/*** @ Author yyp * @ file name Message. java * @ function encapsulate user chat content * @ Blog http://blog.csdn.net/gisredevelopment */public class Message {private String user; private String date; private String content ;}
4 Page code-Logon
<% @ Page language = "java" contentType = "text/html; charset = UTF-8" pageEncoding = "UTF-8" %>
Login
5 page code-chat
<% @ Page language = "java" contentType = "text/html; charset = UTF-8" pageEncoding = "UTF-8" %> <% String user = (String) session. getAttribute ("user"); %>
Chat Room<Script type = "text/javascript" src = "/imgr? Src = http % 3A % 2F % 2Fwww.ineeke.com % 2 Farchives % 2F1486% 2Fjquery-1.10.1.min.js "> </script> <script type =" text/javascript ">$ (function () {(function getMessages () {$. ajax ({dataType: "json", url: 'getmessages ', cache: false, success: function (data) {var v = $ (' # text '). val (); v + = '\ r \ n' + data. date + ''+ data. user + ':' + data. content; $ ('# text '). val (v );}}). always (function () {getMessages () ;}) () ;$ ('# form '). submit (function (event) {event. preventDefault (); var values = $ (this ). serialize (); $. post ('setmessage', values, function (data) {$ ('# form> [name = content]'). val ('') ;}, 'json') ;}; $ ('# logout '). click (function () {$. ajax ({dataType: "json", url: 'logout', cache: false, success: function (data) {window. location. href = 'index. jsp ';}}) ;}); </script>Welcome: <% = user %>