使用Hyperf框架实现websocket聊天室
- 安装,我这边是安装2.0.18的那个版本的
composer require hyperf/websocket-server
- 配置Server,在config/autoload/server.php中追加
use Hyperf\Server\Server;
use Hyperf\Server\SwooleEvent;
.
.
.
.
return [
'mode' => SWOOLE_PROCESS,
'servers' => [
[
'name' => 'ws',
'type' => Server::SERVER_WEBSOCKET,
'host' => '0.0.0.0',
'port' => 9502,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
SwooleEvent::ON_HAND_SHAKE => [Hyperf\WebSocketServer\Server::class, 'onHandShake'],
SwooleEvent::ON_MESSAGE => [Hyperf\WebSocketServer\Server::class, 'onMessage'],
SwooleEvent::ON_CLOSE => [Hyperf\WebSocketServer\Server::class, 'onClose'],
],
],
],
'settings' => [
'enable_coroutine' => true,
'worker_num' => swoole_cpu_num(),
'pid_file' => BASE_PATH . '/runtime/hyperf.pid',
'open_tcp_nodelay' => true,
'max_coroutine' => 100000,
'open_http2_protocol' => true,
'max_request' => 0,
'socket_buffer_size' => 2 * 1024 * 1024,
'buffer_output_size' => 2 * 1024 * 1024,
],
'callbacks' => [
SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
SwooleEvent::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'],
],
];
- 路由配置config/routes.php,这里的ws要和上面的servers.php配置对应上
Router::addServer('ws', function () {
Router::get('/', 'App\Controller\WebSocketController');
});
- 控制器代码
public function onOpen($server, Request $request): void
{
var_dump($request->fd . '进来了');
$this->send($request->fd,'进入聊天室');
// todo 这里把用户fd记录下来,可以使用数据库或者redis保存
$server->push($request->fd, '进入聊天室');
}
public function onClose($server, int $fd, int $reactorId): void
{
var_dump('closed');
var_dump('退出的fd为:' . $fd);
$user= new User();
$this->send($fd,'退出聊天室');
$user::query()->where('user_id', $fd)->delete();
}
public function onMessage($server, Frame $frame): void
{
// 对所有人广播
$user = new User();
$res = $user::query()->get();
foreach ($res as $k=>$v){
$server->push($v->user_id, $frame->data);
}
}
/**
* @Inject
* @var Sender
*/
protected $sender;
public function send(int $fd,string $msg)
{
$this->sender->push($fd, $msg);
return '';
}
然后前端调用页面:详情请点击这里前端页面