前端使用event-source-polyfill
來(lái)SSE請(qǐng)求,因?yàn)樾枰獢y帶token,后端在控制器中寫了讓如下方法。
其中$connection->getStatus()
值都是:8。前端錯(cuò)誤:
<?php
namespace plugin\api\app\controller;
use plugin\api\app\model\UserModel;
use support\Db;
use support\Log;
use support\Request;
use support\Response;
use Tinywan\Jwt\JwtToken;
use Workbunny\WebmanIpAttribution\Location;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\ServerSentEvents;
use Workerman\Timer;
class UserController extends Base
{
protected $userModel = null;
public function __construct()
{
$this->userModel = new UserModel();
}
/**
* 獲取用戶蘇哦有錢包余額
* @param Request $request
* @return Response
* @throws \Webman\Push\PushException
*/
public function getUserWalletBalance(Request $request)
{
$uid = JwtToken::getCurrentId();
var_dump($request->header('accept'));
// 使用SSE推送
if ($request->header('accept') === 'text/event-stream') {
$connection = $request->connection;
// var_dump($connection);
$connection->send(new Response(200, [
'Content-Type' => 'text/event-stream'
], "\r\n"));
//定時(shí)向客戶推送數(shù)據(jù)
$timerId = Timer::add(1, function () use ($connection, &$timerId) {
// 連接關(guān)閉的時(shí)候要將定時(shí)器刪除,避免定時(shí)器不斷累積導(dǎo)致內(nèi)存泄漏
if ($connection->getStatus() !== TcpConnection::STATUS_ESTABLISHED) {
Timer::del($timer_id);
return;
}
// 發(fā)送message事件,事件攜帶的數(shù)據(jù)為hello,消息id可以不傳
$connection->send(new ServerSentEvents(['event' => 'message', 'data' => 'hello', 'id' => 1]));
});
return;
}
}
}
http://www.wtbis.cn/q/10107 按這里的意思?是不能在控制器里面實(shí)現(xiàn)嗎
參考下面代碼
<?php
namespace app\controller;
use support\Request;
use support\Response;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\ServerSentEvents;
use Workerman\Timer;
class StreamController
{
public function index(Request $request): Response
{
$connection = $request->connection;
$id = Timer::add(1, function () use ($connection, &$id) {
// 連接關(guān)閉時(shí),清除定時(shí)器
if ($connection->getStatus() !== TcpConnection::STATUS_ESTABLISHED) {
Timer::del($id);
}
$connection->send(new ServerSentEvents(['data' => 'hello']));
});
return response('', 200, [
'Content-Type' => 'text/event-stream',
'Cache-Control' => 'no-cache',
'Connection' => 'keep-alive',
]);
}
}
js
var source = new EventSource('http://127.0.0.1:8787/stream');
source.addEventListener('message', function (event) {
var data = event.data;
console.log(data); // 輸出 hello
}, false)
按上面示例定時(shí)器也執(zhí)行了,前端500 Internal Server Error
1.后端路由
Route::get('/sse', [StreamController::class, 'index'])->name('sse.stream');
2.前端監(jiān)聽(tīng)
const url = /api/sse?&Authorization=Bearer ${token}
;
const { data } = useEventSource(url, [], {
autoReconnect: {
delay: 1000,
onFailed() {
console.error('重連失敗.');
},
retries: 3,
},
});
500 Internal Server Error