在项目根目录下执行:
php think make:listener WebSocketEvent
在swoole.php
的websocket['subscribe']
写入监听并开启websocket
'enable' => true,
'subscribe' => [
app\listener\WebSocketEvent::class
],
WebsocketEvent.php
<?php
declare (strict_types = 1);
namespace app\listener;
use app\Request;
use Swoole\Server;
use think\Container;
use think\swoole\Table;
use think\swoole\Websocket;
use think\cache\driver\Redis;
class WebsocketEvent
{
protected $websocket = null; //websocket对象
protected $server = null; //server对象
protected $redis = null; //redis对象
public function __construct(Server $server, Websocket $websocket)
{
$this->websocket = $websocket;//依赖注入的方式
$this->server = $server;
$this->redis = new Redis;
}
//onOpen触发的事件,传入的是一个request对象
public function onConnect(Request $request)
{
//通过websocket的上下文取得fd:$this->websocket->getSender()
$fd = $this->websocket->getSender();
//$this->server->push($fd, 'hello swoole');
//把用户存到redis
$this->redis->zadd('member', 0, $fd);
//广播用户上线
$members = $this->redis->zrange('member', 0, -1);
foreach($members as $member){
$this->server->push((int)$member, "{$fd}上线");
}
}
//onClose触发的事件
public function onClose()
{
//将离线的用户从关系表中移除
$fd = $this->websocket->getSender();
$res = $this->redis->zrem('member', $fd);
//var_dump($fd, $res);
}
}
开启服务
php think swoole
Starting swoole http server...
Swoole http server started: <http://127.0.0.1:88>
You can exit with `CTRL-C`
前端测试代码
if ("WebSocket" in window)
{
alert("您的浏览器支持 WebSocket!");
// 打开一个 web socket
var ws = new WebSocket("ws://127.0.0.1:88");
ws.onopen = function()
{
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("发送数据");
console.log("数据发送中...");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
console.log("数据已接收...");
};
ws.onclose = function()
{
// 关闭 websocket
console.log("连接已关闭...");
};
}
else
{
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}