第一步:安装组件
composer require hyperf/websocket-server
第二步:配置文件配置 websocket 服务
<?php
// config/autoload/server.php
'servers' => [
// websocket 服务
[
// 服务名称,注意这个名称,后续要用到
'name' => 'ws',
'type' => Server::SERVER_WEBSOCKET,
'host' => '0.0.0.0',
'port' => 9509,
// TCP 连接
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_OPEN => [\App\Controller\Server\WebSocketServerController::class, 'onOpen'],
Event::ON_MESSAGE => [\App\Controller\Server\WebSocketServerController::class, 'onMessage'],
Event::ON_CLOSE => [\App\Controller\Server\WebSocketServerController::class, 'onClose'],
]
],
],
第三步:添加服务路由
// 注意:这里的 ws 要和配置文件中 websocket 服务的 name 值一样
Router::addServer('ws', function () {
Router::get('/', \App\Controller\Server\WebSocketServerController::class);
});
第四步:创建 websocket 服务类
<?php
// App\Controller\Server\WebSocketServerController.php
namespace App\Controller\Server;
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
class WebSocketServerController implements OnMessageInterface,OnOpenInterface,OnCloseInterface
{
public function onOpen($server, $request): void
{
echo $request->fd . ' 号客户端已连接' . PHP_EOL;
$server->push($request->fd, '服务端告诉你,你的id是: '.$request->fd);
}
public function onMessage($server, $frame): void
{
$data = json_decode($frame->data, true);
$userId = (int)$data['userId'];
$message = $data['message'];
//实现对话
if($frame->fd != $userId){
$server->push($userId, $frame->fd.'号客户端对你说: '.$message);
}else{
//不填写id时发送给原客户端
$server->push($frame->fd, '你对自己说: '.$message);
}
}
public function onClose($server, int $fd, int $reactorId): void
{
echo $fd . '断开连接,处理线程是 ' . $reactorId . PHP_EOL;
}
}
第五步:启动服务
php bin/hyperf.php start
第六步:创建 websocket 客户端
该文件位置随意
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>聊天室</title>
</head>
<body>
<div>
<input type="text" id="userId" placeholder="请输入ID">
<input type="text" id="message" placeholder="请输入消息">
<button onclick="sendMessage()">发送</button>
</div>
<div id="chatBox"></div>
<script>
// 创建 WebSocket 连接
const ws = new WebSocket('ws://192.168.0.99:9509');
// 监听 WebSocket 连接事件
ws.onopen = function (event) {
console.log('WebSocket 连接已打开');
};
// 监听 WebSocket 接收消息事件
ws.onmessage = function (event) {
const message = event.data;
const chatBox = document.getElementById('chatBox');
chatBox.innerHTML += '<p>' + message + '</p>';
};
//监听WebSocket 连接已关闭
ws.onclose = function(event) {
console.log('WebSocket 连接已关闭');
};
// 发送消息
function sendMessage() {
const userId = document.getElementById('userId').value;
const message = document.getElementById('message').value;
const data = {
userId: userId,
message: message
};
ws.send(JSON.stringify(data));
document.getElementById('userId').value = "";
document.getElementById('message').value = "";
}
</script>
</body>
</html>
注意事项
除了要映射9501端口还要映射9509端口
结果