WebSocket与长轮询

为了实现实时更新或类似于聊天室的应用

  1. 一开始想到的肯定是配合setTimeout每隔一小段时间就给服务器发送请求,但是这样给服务器的压力很大,不够随机应变太耗费资源

  2. 第二个尝试地是长轮询,顾名思义,是服务器发出一个时间比较长的请求。比如时间设定为30秒,在30秒之内,如果收到服务器更新的数据,则进行对应的操作之后再发出请求,如果在30秒之内没有收到返回数据则执行error回调函数继续发出请求。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function Ask(){
    $.ajax({
    url: "http://47.92.139.26:8080/spring-boot-panda-0.0.1-SNAPSHOT/question/getNew/" + lastId + "/" + questionId
    dataType: "json",
    async: "true",
    timeout: "30000",
    //服务器发出一个30秒的请求
    success: function(msg) {
    done
    Ask();
    },
    error: function() {
    done
    Ask();
    }
    })
    }

    这种操作比起第一种肯定会比较节约资源,但是本质还是没有改变,还是客户端和服务器之间的单向对话,不够随机应变:D

  3. 最后使用了WebSocket,操作简单体验感很好:accept:

    (记得引入对应的WebSocket包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//打开双通道
function connect(){
var socket = new SockJS('http://47.92.139.26:8080/spring-boot-panda-0.0.1-SNAPSHOT/endpointAnswer');
//新建一个WebSocket对象

stompClient = Stomp.over(socket);
//使用STMOP子协议的WebSocket客户端

stompClient.connect({},function(frame){
//连接WebSocket服务端

//广播接收信息
stompTopic();
QuesTest = 1;
localStorage.setItem('QuesTest', QuesTest);

});
}

//关闭双通道
function disconnect(){
if(stompClient != null) {
stompClient.disconnect();
}
console.log("Disconnected");
}

//广播(一对多) = 接收服务器传过来的消息
function stompTopic(){
//通过stompClient.subscribe订阅目标(destination)发送的消息(广播接收信息)
stompClient.subscribe('/answerMass/getNew',function(response){
done
});
}

//群发 = 发送消息
function sendMassMessage(){
done
}

WebSocket和之前两种方式的原理都不一样,WebSocket可以打开双通道,做到请求不止可以有客户端发起也可以有服务器发出来,实现了双向对话,节约资源。一般有四个函数:打开双通道,接收服务器发送的消息,给服务器发消息,关闭双通道。

总结: WebSocket真香!