Swoole-WebSocket服務端主動推送消息
標簽(空格分隔): websocket swoole php
WebSocket服務器代碼
<?php
namespace swoole\websocket;
class WebSocketServer
{
var $server;
public function __construct()
{
$this->server = new \Swoole\WebSocket\Server("0.0.0.0", 9991);
print "WebSocketServer: 0.0.0.0, 9991" . PHP_EOL;
$this->server->set([
'task_worker_num' =>4
]);
$this->server->on('open', [$this, 'open']);
$this->server->on('message', [$this, 'message']);
$this->server->on('task', [$this, 'task']);
$this->server->on('finish', [$this, 'finish']);
$this->server->on('request', [$this, 'request']);
$this->server->on('close', [$this, 'close']);
$this->server->start();
}
/**
* $request 是一個 HTTP 請求對象,包含了客戶端發來的握手請求信息
* onOpen 事件函數中可以調用 push 向客戶端發送數據或者調用 close 關閉連接
* onOpen 事件回調是可選的
* @param \Swoole\WebSocket\Server $server
* @param \Swoole\Http\Request $request
*/
public function open($server, $request)
{
$fd = $request->fd;
echo "server: handshake success with fd{$fd}" . PHP_EOL;
}
/**
* $frame 是 Swoole\WebSocket\Frame 對象,包含了客戶端發來的數據幀信息
* onMessage 回調必須被設置,未設置服務器將無法啟動
* 客戶端發送的 ping 幀不會觸發 onMessage,底層會自動回復 pong 包,也可設置 open_websocket_ping_frame 參數手動處理
* @param \Swoole\WebSocket\Server $server
* @param \Swoole\WebSocket\Frame $frame
*/
public function message($server, $frame)
{
$data = json_decode($frame->data, true);
var_dump("---收到消息----fd:{$frame->fd}");
var_dump($data);
$server->task($data);
// 保持連接 心跳檢測
if ($data['type'] == 'ping') {
$server->push($frame->fd, json_encode(['type' => 'ping', 'data' => 'tong']));
}
}
/**
* @param \Swoole\WebSocket\Server $server
* @param $fd
*/
public function close($server, $fd)
{
echo "fd:{$fd} close" . PHP_EOL;
}
/**
* @param \Swoole\Server $server
* @param int $taskId
* @param int $srcWorkerId
* @param mixed $data
*/
public function task($server, $taskId, $srcWorkerId, $data)
{
echo "正在處理任務----taskId:{$taskId}" . PHP_EOL;
sleep("3");
$server->finish("ok");
}
/**
* @param \Swoole\Server $server
* @param int $task_id
* @param mixed $data
*/
public function finish($server, $taskId, $data)
{
echo "任務處理成功-----taskId:{$taskId}";
}
public function request(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
{
echo "服務端主動推送消息......" . PHP_EOL;
if ($request->server['path_info'] == "/websocket/") {
foreach ($this->server->connections as $fd) {
if ($this->server->isEstablished($fd)) {
$this->server->push($fd, json_encode(['type' => 3, 'data' => '系統消息推送' . mt_rand(1000, 9999)]));
}
}
}
}
}
new WebSocketServer();
客戶端(JS)
<script>
document.addEventListener("DOMContentLoaded", function() {
var wsServer = 'ws://web.test.com/wss';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("已連接上服務器");
};
//每隔5秒鍾發送一次心跳,避免websocket連接因超時而自動斷開
window.setInterval(function(){
var ping = {"type":"ping"};
websocket.send(JSON.stringify(ping));
},10000);
websocket.onclose = function (evt) {
console.log("連接已關閉");
};
websocket.onmessage = function (evt) {
data = eval("("+evt.data+")");
if (data.type == "ping") {
return;
}
console.log('接受信息: ' + data.data);
};
});
客戶端(php)
$result = curl_get("http://0.0.0.0:9991/websocket/");