采用http协议做IM拉取消息的流程设计

接手一个在线客服的项目,本质上就是一个 IM 项目。

第一个想到的是用 WebSocket,然而一些客观因素导致这个项目很难采用 WebSocket 来做。那么,就只好用 http 实现,并为此设计了如下流程:

如图,首先 Browser 端发起一个拉取消息的请求。Server 端收到请求后,立即查询是否有新消息,如查询到了新消息,则立即返回结果给 Browser 端。

Browser 端收到返回结果后,再次发起一个新的拉取消息的请求,如此往复进行。

若 Server 端接到拉取请求后,没有查询到新消息,则 Hold 住这个请求进程,同时设置一个时间阈值,比如5秒。

在这5秒内,Server 端反复查询是否有新消息,当发现了新消息后,则立即向 Browser 端返回结果同时结束掉进程。若始终都没有新消息,则在达到预设的时间阈值后,向 Browser 端返回一个通知,告知 Browser 端这次没有新消息。

在这个流程中,Browser 端发出请求后,可能会立即收到结果,也可能在5秒后得知没有新消息,不论是否有新消息,在得到 Server 端反馈后,都要立即再次发出请求。

阳光部落原创,更多内容请访问http://www.sunbloger.com/

利用Swoole实现服务器通过WebSocket主动向浏览器推送数据

WebSocket 协议是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信,允许服务器主动发送信息给客户端。

下面的代码演示了利用 Swoole 实现服务器向浏览器主动推送数据的例子。

Server端代码:

<?php
$server = new Swoole\Websocket\Server('192.168.1.1', 9501);

$server->on('Open', function($server, $req) {
    echo 'connection open: '.$req->fd . "\n";
    $server->push($req->fd, "welcome to www.sunbloger.com");
    for ($i=1; $i<=9; $i++) {
        $server->push($req->fd, $i);
        sleep(3);
    }
});

$server->on('Message', function($server, $req) {
    echo "client(".$req->fd."): " . $req->data . "\n";
});

$server->on('Close', function($server, $fd) {
    echo "connection close: {$fd}\n";
});

$server->on('WorkerStart', function ($server, $workerId) {
    echo "worker started: {$workerId}\n";
});

$server->start();
?>

 

浏览器端(Client)代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>WebSocket Client</title>
</head>
<body>  
  <input type="text" id="text">
  <input type="submit" value="发送数据" onclick="send()">
  <div id="msg"></div>
</body>
<script>
var isSupport;

if (typeof WebSocket != 'undefined') {
    isSupport = true;
} else {
    isSupport = false;
}

if (isSupport == true) {
    var msg = document.getElementById("msg");
    var wsServer = 'ws://192.168.1.1:9501';
    var websocket = new WebSocket(wsServer);
    websocket.onopen = function (e) {
        console.log("websocket server open.");
    };
    
    websocket.onmessage = function (e) {
        msg.innerHTML += e.data +'<br>';
    }
    
    websocket.onclose = function (e) {
        console.log("websocket server close.");
    };
    
    
}

function send() {
    if (isSupport == true) {
        var text = document.getElementById('text').value;
        document.getElementById('text').value = ''; //向服务器发送数据
        websocket.send(text);
    } else {
        alert("浏览器不支持WebSocket!");
    }
}

</script>
</html>

 

阳光部落原创,更多内容请访问http://www.sunbloger.com/