IM message communications web page version

Long polling: the client sending a request every 10-20 seconds, and then send the request based on the fracture once the request, a request to get the rear end, the data acquisition cycle, where the data can not obtain the Thread.sleep case (300) ; short time, and then the cycle, then no data can be recycled directly back to N times no data, a request is completed, then disconnect, then the next request sending client.

 

 

 

HTTP-based long connection, a poll by a long way to achieve "server push" technology, it makes up for the lack of a simple HTTP request response mode, which greatly enhances the real-time and interactive programs.

First, what is the connection long, long polling?

It is to keep the client sends a request in plain words to the server to get the latest data. Here the "non-stop" is actually stopping there, but we can not tell whether to stop the human eye, it's just a quick stop and then immediately start to connect it.

Second, a long connection, long polling application scenario

Long connection, long polling general application and WebIM, ChatRoom some sites and applications need to interact in a timely manner. Its true cases are: WebQQ, Hi web version, Facebook IM and so on.

If you are interested in Reverse Ajax server-side, you can refer to this article DWR Reverse Ajax server-side push way: http://www.cnblogs.com/hoojo/category/276235.html

Third, the advantages and disadvantages

Polling: The client periodically send Ajax request to the server, the server returns a response immediately after receiving the request message and closes the connection. 
Pros: the back-end programming easier. 
Cons: There are more than half of the request is useless and a waste of bandwidth and server resources. 
Example: suitable for small applications.


Long polling: the client sends a request to the server Ajax, hold live connection server upon request, does not return until a new message response information and close the connection, the client sends a new response information after their request to the server. 
Advantages: not frequently request message without a case, small consumption of resources. 
Cons: server hold the connection will consume resources, to ensure that no data is returned order, difficult to manage and maintain. 
Examples: WebQQ, Hi web version, Facebook IM.

 

Long connection: embedding in the page a hidden iframe Zao, Zao this hidden iframe src attribute set to a long connection request or using xhr request, the server can be a steady stream of input data to the client. 
Advantages: Instant message arrival, do not send useless request; also is relatively easy to manage. 
Cons: server maintains a persistent connection will increase overhead. 
Examples: Gmail chat


Flash Socket: within a page is embedded into the Socket class using the JavaScript program Flash Socket Socket server interface provided by the calling program interface to communicate this Flash, JavaScript after receiving the message transmitted from the control server the displayed page. 
Pros: true instant communication, rather than a pseudo-real-time. 
Cons: The client must install the Flash plug-in; non-HTTP protocol, can not automatically pass through the firewall. 
Example: network interactive games.

 

Fourth, implement the principle of

The so-called long connections, is to create and maintain a stable and reliable connection between the client and the server. In fact, it is a very early presence of technology, but due to the relatively slow development of browser technology, does not provide good support for the realization of such a mechanism. So to achieve this effect, it requires the client and server programs cooperate to jointly complete. The usual practice is adding an infinite loop in the application server, the change of monitoring data in a loop. When a new data is immediately output to the browser and disconnects, after receiving the data browser, initiates a request again to the next cycle, it is often said long polling (long-polling) mode. As shown below, which typically contains the following key procedures:

image

1. establish polling 
process of establishing polling is very simple, the browser initiates a request to enter the wait state loop, this time because the server has not yet made a response, so HTTP has been in a connected state. 
2. Push data 
during cycling, the server program to monitor changes in the data, such as an update is found, outputs the information to the browser, then disconnect completion response process to achieve "server push." 
3. Polling termination of 
polling may be terminated in the following three cases: 
  3.1 push new data 
   when the cycle server to push information to the browser, should take the initiative to end the program so that connection is lost, so that the browser can the timely receipt of data. 
  3.2. No new data push 
   cycle can not continue, should set a maximum time limit, avoid WEB server timeout (Timeout), if there has been no new information, the server should take the initiative to send this poll No new information is normal to the browser response, and disconnect, which is also referred to as a "heartbeat" message. 
  3.3. The network failure or abnormal 
   request a timeout or an error due to the network failure caused by factors may also cause unexpected interruption of polling, then the browser will receive an error message. 
4. reconstruction of polling 
the browser process and the corresponding reply is received, it should immediately initiate a request to re-start a new polling cycle.

 

V. Programming

1, ordinary polling Ajax way

Client code fragment

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="author" content="hoojo & http://hoojo.cnblogs.com">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <%@ include file="/tags/jquery-lib.jsp"%>
 
        <script type="text/javascript">
            $(function () {
                window.setInterval(function () {
                    $.get("${pageContext.request.contextPath}/communication/user/ajax.mvc", 
                        {"timed": new Date().getTime()}, 
                        function (data) {
                            $("#logs").append("[data: " + data + " ]<br/>");
                    });
                }, 3000);
            });
        </script>
    </head>
    <body>
        <div id="logs"></div>
    </body>
</html>

Client implementation is to use the result of a general poll, it is relatively simple. Uninterrupted use setInterval to refresh the server's access to resources, the advantage of this approach is simple and timely. The disadvantage is that most of the link is invalid duplicated; no response sequence results (because it is an asynchronous request, when the request does not return a result, when the request has been sent back to the first time if a later request than the previous request. results are returned, then the face of the current request return result data is already outdated the invalid data); requests more difficult to maintain, wasting server and network resources.

 

Server-side code

@RequestMapping("/ajax")
public void ajax(long timed, HttpServletResponse response) throws Exception {
     PrintWriter writer = response.getWriter();
     Random rand = new Random();
     // infinite loop query for data changes
     while (true) {
         Thread.sleep (300); // Sleep 300 msec, an analog processing services, etc.
         int i = rand.nextInt (100); // generates a random number between 0-100
         if (i> 20 && i <56) {// if the random number is between 20-56 as valid data to analog data changes
             long responseTime = System.currentTimeMillis();
             // return data information, request time, return time data, time-consuming
             writer.print("result: " + i + ", response time: " + responseTime + ", request time: " + timed + ", use time: " + (responseTime - timed));
             break; // out of the loop, the return data
         } Else {// analog data without change, to hold live dormant connection
             Thread.sleep(1300);
         }
     }
}

Server-side implementation, here the simulation program monitoring data changes. The above code belongs to a controller in the method SpringMVC, the equivalent of a doPost Servlet / doGet method. If there is no program to adapt to the environment servlet, the method body code to copy the servlet doGet / doPost can be.

 

When the server is connected when the program is designed long, to note the following: 
1. The server program controllability of polling
 
because the polling mode is implemented endless loop, so the algorithm program to ensure that when exit the loop has full control, avoid entering an infinite loop and run out of server resources. 
2. reasonable choice "heartbeat" frequency 
can be seen from Figure 1, a long connection request by the client must be constantly maintained, so to maintain normal "heartbeat" between the client and the server is critical, it should be less than the parameter POLLING_LIFE WEB server timeout, the general recommendation of about 10 to 20 seconds. 
3. Impact of network factors 
in practical application, making the response from the server to the next build cycle, there is a time delay, the length of the delay time by a variety of factors such as the impact of network transmission, at this time, long connection is temporarily disconnected gap, if you happen to have a change of data occurred during this time, the server is unable to push immediately, so in algorithm design to be solved due to the delay may cause data loss problems. 
4. The performance of the server 
in the long connection applications, each client with the server instance to maintain a persistent connection, which will consume a large amount of server resources, especially in some large-scale applications especially in a large number of concurrent connections has long could lead to new request is blocked and even system crashes, therefore, should pay special attention during programming algorithm optimization and improvement, if necessary, to consider load balancing and server clustering technology.

image

The figure is the result of the return, you can see first request, it will not necessarily be the first to return results. This order can not be guaranteed, resulting in unwanted dirty data or connection request. Visible waste of resources, server or network.

 

2, the general polling mode iframe

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <%@ include file="/tags/jquery-lib.jsp"%>
        <script type="text/javascript">
            $(function () {
                window.setInterval(function () {
                    $("#logs").append("[data: " + $($("#frame").get(0).contentDocument).find("body").text() + " ]<br/>");
                    $("#frame").attr("src", "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime());
                    // 延迟1秒再重新请求
                    window.setTimeout(function () {
                        window.frames["polling"].location.reload();
                    }, 1000);
                }, 5000);
            });
        </script>
    </head>
    <body>
        <iframe id="frame" name="polling" style="display: none;"></iframe>
        <div id="logs"></div>
    </body>
</html>

 

这里的客户端程序是利用隐藏的iframe向服务器端不停的拉取数据,将iframe获取后的数据填充到页面中即可。同ajax实现的基本原理一样,唯一不同的是当一个请求没有响应返回数据的情况下,下一个请求也将开始,这时候前面的请求将被停止。如果要使程序和上面的ajax请求一样也可以办到,那就是给每个请求分配一个独立的iframe即可。下面是返回的结果:

image

其中红色是没有成功返回请求就被停止(后面请求开始)掉的请求,黑色是成功返回数据的请求。

 

3、长连接iframe方式

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="author" content="hoojo & http://hoojo.cnblogs.com">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <%@ include file="/tags/jquery-lib.jsp"%>
        <script type="text/javascript">
            $(function () {
                window.setInterval(function () {
                    var url = "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime();
                    var $iframe = $('<iframe id="frame" name="polling" style="display: none;" src="' + url + '"></iframe>');
                    $("body").append($iframe);
                    $iframe.load(function () {
                        $("#logs").append("[data: " + $($iframe.get(0).contentDocument).find("body").text() + " ]<br/>");
                        $iframe.remove();
                    });
                }, 5000);
            });
        </script>
    </head>
    <body>
        <div id="logs"></div>
    </body>
</html>

 

 

这个轮询方式就是把刚才上面的稍微改下,每个请求都有自己独立的一个iframe,当这个iframe得到响应的数据后就把数据push到当前页面上。使用此方法已经类似于ajax的异步交互了,这种方法也是不能保证顺序的、比较耗费资源、而且总是有一个加载的条在地址栏或状态栏附件(当然要解决可以利用htmlfile,Google的攻城师们已经做到了,网上也有封装好的lib库),但客户端实现起来比较简单。

 image

如果要保证有序,可以不使用setInterval,将创建iframe的方法放在load事件中即可,即使用递归方式。调整后的代码片段如下:

 

 

<script type="text/javascript">
    $(function () {
        (function iframePolling() {
            var url = "${pageContext.request.contextPath}/communication/user/ajax.mvc?timed=" + new Date().getTime();
            var $iframe = $('<iframe id="frame" name="polling" style="display: none;" src="' + url + '"></iframe>');
            $("body").append($iframe);
 
            $iframe.load(function () {
                $("#logs").append("[data: " + $($iframe.get(0).contentDocument).find("body").text() + " ]<br/>");
                $iframe.remove();
 
                // 递归
                iframePolling();
            });
        })();    
    });
</script>

 

这种方式虽然保证了请求的顺序,但是它不会处理请求延时的错误或是说很长时间没有返回结果的请求,它会一直等到返回请求后才能创建下一个iframe请求,总会和服务器保持一个连接。和以上轮询比较,缺点就是消息不及时,但保证了请求的顺序。

 

4、ajax实现长连接

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <%@ include file="/tags/jquery-lib.jsp"%>
 
        <script type="text/javascript">
            $(function () {
                (function longPolling() {
                    $.ajax({
                        url: "${pageContext.request.contextPath}/communication/user/ajax.mvc",
                        data: {"timed": new Date().getTime()},
                        dataType: "text",
                        timeout: 5000,
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            $("#state").append("[state: " + textStatus + ", error: " + errorThrown + " ]<br/>");
                            if (textStatus == "timeout") { // 请求超时
                                    longPolling(); // 递归调用
 
                                // 其他错误,如网络错误等
                                } else { 
                                    longPolling();
                                }
                            },
                        success: function (data, textStatus) {
                            $("#state").append("[state: " + textStatus + ", data: { " + data + "} ]<br/>");
 
                            if (textStatus == "success") { // 请求成功
                                longPolling();
                            }
                        }
                    });
                })();
            });
        </script>
    </head>
    <body>

The above code is the only way to complete a long connection Ajax, the main advantage is, and always maintain a server connection. If the current connection request is successful, we will continue to update the data and create a new connection and the server to keep in touch. If the connection time-out or an exception occurs, this time the program will continue to create a new connection request. This saves the server and network resources, improving the performance of the program, thus ensuring the sequential program.

image

 

VI Summary

Modern browsers support cross-domain resource sharing (Cross-Origin Resource Share, CORS) specification, which allows cross-domain XHR requests, so the script-based and iframe-based technology has become an outdated needs.

As the Comet and Reverse Ajax implementations best way is through the use of the XMLHttpRequest object, the approach provides a real connection handle and error handling. Of course, you choose a long polling via HTTP using the XMLHttpRequest object (a simple Ajax request to the server pending) of Comet mode, all Ajax-enabled browsers also support such a practice.

HTTP-based long connection technology, is ideal for real-time interactive class application development in native browser environment, with the rapid development of the browser, html5 will provide better support and more widely used. There html5 in a very friendly websocket can complete this long connection technology, the Internet also has information on relevant aspects, no longer here to do too much introduction.

 

Reference: https://www.cnblogs.com/AloneSword/p/3517463.html

Guess you like

Origin blog.csdn.net/shaolong1013/article/details/91039978