# hyperf实时消息 **Repository Path**: stfeng/hyperf_real_time_message ## Basic Information - **Project Name**: hyperf实时消息 - **Description**: 用于推送消息服务; 业务。 1.【创建连接】用户携带已登录的token创建ws连接, 2.【ws服务端验证登录状态】服务端根据token访问远程api接口获取用户id 3.【其他任意服务器,通过访问httpapi接口,执行业务推送等服务】 # api提供功能 1.推送消息 1.1全站推送消息 1.2指定用户推送消息,支持多用户群发 1.3指定多用户推送不同消息。 2.连接管理 2.1 断开全站连接 2.2 断开指定用户的连接 2.3 断开指定连接id 2.4 获取用户的连接id - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2023-07-21 - **Last Updated**: 2023-07-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # websocket推送消息服务 >author:yichen >email:2782268022@qq.com >frame:hyperf # 简述 用于推送消息服务; 业务。 1.【创建连接】用户携带已登录的token创建ws连接, 2.【ws服务端验证登录状态】服务端根据token访问远程api接口获取用户id 3.【其他任意服务器,通过访问httpapi接口,执行业务推送等服务】 # 安装 1.安装hyperf 请参考 hyperf官网,先安装hyperf ``` https://doc.hyperf.io/#/zh-cn/quick-start/install ``` 2.安装项目应用 ``` composer create-project tanyichen/httptowebsocket_hyperf ``` 3.把项目应用替换进hyperf 3.1 主要替换的几个目录或文件 3.1.1 app 应用目录 controller 控制器 middleware 中间件 3.1.2 config 配置目录 routes autoload api redis server middlewares 4. 根据config/server.php开启的服务,端口放行 5.启动服务 php bin/hyperf.php start 6.使用 1.使用websocket客户端 连接ws服务 2.推送信息 查看router路由,根据http的api接口使用推送等相关服务 7.使用前注意 需要搭建websocket前,你已经有自己的api服务,并且有获取uid的api接口,把这个url接口地址配置到api.php上。 使用我们websocket服务的时候,用户端在创建websocket连接时会调用这个外部api接口获取到该用户的uid # api提供功能 1.推送消息 1.1全站推送消息 1.2指定用户推送消息,支持多用户群发 1.3指定多用户推送不同消息。 2.连接管理 2.1 断开全站连接 2.2 断开指定用户的连接 2.3 断开指定连接id 2.4 获取用户的连接id # 配置 1.配置文件目录 config/autoload/ 2.外部依赖接口配置 api.php 3.服务配置 server.php ws端口为9501 http端口为9701 预留端口9601 为未来分布式服务互通拓展预留 # 路由 config/routes.php # 对外接口鉴权中间件 app/middleware/auth/manage.php 1. 使用方式1 单点拦截,通过路由进行配置哪些接口需要中间件进行拦截鉴权。 2. 使用方式2 全局拦截,通过config/autoload/middlewares.php 根据server.php的服务全局协议拦截 # redis配置注意 config/autoload/redis.php wsFd 专用 用户连接fd绑定uid wsUid 专用 用户uid绑定用户连接fd 如有更多redis需求,请新建其他redis节点。 # 项目目录 ``` app ├── Aspect // 切面 │ ├── amqp.php // 用于管理 AMQP 组件 │ └── server.php // 用于管理 ├── Controller // 控制器 │ ├── Http // http控制器 │ │ ├── Api // 接口目录 │ │ │ ├── ManageConnections.php // 连接管理 │ │ │ ├── Abnormal.php // 异常信息处理 │ │ │ └── Push.php // 消息推送 │ │ ├── Base.php // 基类 │ │ └── Index.php // 暂不开放,用于测试 │ └── Websocket // websocket控制器 │ ├── AbstractController.php // 用于管理 AMQP 组件 │ ├── Index.php // ws服务默认控制器 │ └── Wss.php // wss服务控制器 ├── middleware // 中间件 │ └── auth // 授权目录 │ ├── Manage.php // 管理权限 │ └── config ├── autoload // 此文件夹内的配置文件会被配置组件自己加载,并以文件夹内的文件名作为第一个键值 │ ├── api.php // 依赖外部的api接口 │ ├── aspects.php // 用于管理 AOP 切面 │ ├── consul.php // 用于管理 Consul 客户端 │ ├── databases.php // 用于管理数据库客户端 │ ├── middlewares.php // 用于管理中间件 │ ├── redis.php // 用于管理 Redis 客户端 │ └── server.php // 用于管理 Server 服务 │ ………………更多配置信息请参考hyperf框架自行配置 ├── config.php // 用于管理用户或框架的配置,如配置相对独立亦可放于 autoload 文件夹内 ├── container.php // 负责容器的初始化,作为一个配置文件运行并最终返回一个 Psr\Container\ContainerInterface 对象 ├── dependencies.php // 用于管理 DI 的依赖关系和类对应关系 └── routes.php // 用于管理路由 ``` Docker 下开发 假设您的本机环境并不能达到 Hyperf 的环境要求,或对于环境配置不是那么熟悉,那么您可以通过以下方法来运行及开发 Hyperf 项目: # 创建网关 如果不使用默认网关,可以自己创建一个固定网关 ``` docker network create --subnet=192.168.10.1/24 network_my ``` # 下载并运行 hyperf/hyperf环境镜像,并将镜像内的项目目录绑定到宿主机的 /www/wwwroot/skeleton 目录 ``` docker run --name hyperf --hostname hyperf -v /www/wwwroot/skeleton:/hyperf-skeleton --net network_my --ip 192.168.10.30 -d -P -p 9501:9501 -p 9701:9701 -p 9601:9601/udp -itd --entrypoint /bin/sh hyperf/hyperf:7.2-alpine-cli ``` # 镜像容器运行后,在容器内安装 Composer ``` wget https://github.com/composer/composer/releases/download/1.8.6/composer.phar chmod u+x composer.phar mv composer.phar /usr/local/bin/composer ``` # 将 Composer 镜像设置为阿里云镜像,加速国内下载速度 ``` composer config -g repo.packagist composer https://mirrors.aliyun.com/composer ``` # 通过 Composer 安装 tanyichen/httptowebsocket_hyperf 项目 ``` composer create-project tanyichen/httptowebsocket_hyperf ``` # 进入安装好的 Hyperf 项目目录 ``` cd hyperf-skeleton/httptowebsocket_hyperf ``` 如果当前目录不对,你可以用ls命令查看下目录。找到这个启动目录即可。 # 启动 Hyperf ``` php bin/hyperf.php start ``` # 替换项目 到这里运行环境基本没问题了,然后删除项目,把我们到项目拷贝进 hyperf-skeleton 目录下进行替换 ``` composer install #安装依赖 ``` #启动 ``` php bin/hyperf.php start ``` 默认是ws协议,如果想支持wss,建议配置nginx 配置方法如下: ``` server { listen 80; listen 443 ssl; server_name www.域名.com; #这里填你的域名 ssl on; ssl_certificate 证书.crt; #这里填证书地址 ssl_certificate_key 证书.key; #这里填证书地址 ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_protocols SSLv3 SSLv2 TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_prefer_server_ciphers on; location /wss/ { proxy_pass http://127.0.0.1:9701/; #通过配置端口指向部署websocker的项目的路由,用http协议 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; } } 踩坑点: 1注意 /wss/ 前后都有斜杠。 2. 注意proxy_pass 对应的是http,因为ws协议就是走的http通道 3. proxy_set_header X-real-ip $remote_addr; 这里是用户端的ip地址。如果ws里要获取ip。请获取header['X-real-ip']; 4. 客户端链接方法 wss://域名/wss/ 注意尾部增加wss如果要修改,需要新增或修改nginx配置节点location /wss/ ``` 配置方法2 不依赖nginx,需要值router.php 路由配置文件新增wss路由 在config目录下找到server.php ``` [ 'name' => 'wss', 'type' => Server::SERVER_WEBSOCKET, 'host' => '0.0.0.0', 'port' => 9701, 'sock_type' => SWOOLE_SOCK_TCP | SWOOLE_SSL, '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' => [ 'ssl_cert_file' =>'/config/ssl.crt', 'ssl_key_file' => '/config/ssl.key', 'heartbeat_idle_time' => 60, // 表示一个连接如果60秒内未向服务器发送任何数据,此连接将被强制关闭 'heartbeat_check_interval' => 29, // 表示每60秒遍历一次 'open_http2_protocol' => true, ], ], ``` #api开放接口 1.消息推送接口 推送接口 {http:/\/\ip:9701}/api/push/{路由} 1.1 全站推送消息 ``` 请求路由: /all 请求参数: {"data":{"msg":{"msg":"测试","uid":"12345"}},"token":"123456"} 请求方法:POST 请求类型 json ``` 1.2 指定uid推送,支持群发 ``` 请求路由: /uids 请求参数: {"data":{"msg":{"msg":"测试","uid":"12345"},"uids":["123456"]},"token":"令牌"} 请求方法:POST 请求类型 json ``` 1.3 集合推送,支持不同uid推送不同信息 ``` 请求路由: /list 请求参数:{token:'令牌验证',data:{list:[{uid:'uid1','msg':'推送内容'}]}} 请求方法:POST 请求类型 json ``` 2.连接管理接口 推送接口 {http:/\/\ip:9701}/api/manage_connections/{路由} ``` 1.1 强制断开全站连接 请求路由: /close_all 请求参数:{"data":{},"token":"令牌"} 请求方法:POST 请求类型 json 1.2 根据连接fd 强制断开连接,需先根据用户id 到getUidFd获取到fd信息 请求路由: /close_fds 请求参数:{"data":{"fds":["1"]},"token":"令牌"} 请求方法:POST 请求类型 json 1.3 根据uid 断开连接,支持多uid 请求路由: /close_uids 请求参数:{"data":{"uids":["123456"]},"token":"令牌"} 请求方法:POST 请求类型 json 1.4 根据用户uid获取连接fd 请求路由: /uid_fds 请求参数:{"data":{"uid":"123456"},"token":"令牌"} 请求方法:POST 请求类型 json 1.5 根据所有在线用户uid 请求路由: /uid_fds 请求参数:{"data":{},"token":"令牌"} 请求方法:POST 请求类型 json ``` 3.异常信息处理接口 推送接口 {http:/\/\ip:9701}/api/abnormal/{路由} ``` 1.1 获取异常ip列表,每页返回50条ip 请求路由: /ips 请求参数:{"data":{"page":"1"},"token":"令牌"} 请求方法:POST 请求类型 json 1.2 获取ip详情 请求路由: /ips_info 请求参数:{"data":{"ip":"117.0.1.1"},"token":"令牌"} 请求方法:POST 请求类型 json 1.3 删除指定ip记录,支持多个 请求路由: /delete_ips 请求参数:{"data":{"uids":["123456"]},"token":"令牌"} 请求方法:POST 请求类型 json ``` #websocket用户端连接地址 ws连接地址 连接地址 {ws:/\/\ip:9501}&token=1231412313123{路由} ``` 1.1 强制断开全站连接 请求路由: 请求参数:&token=1231412313123 请求方法:WS 请求类型 url ``` wss连接地址 暂未开通 ``` Router::addServer('wss', function () { Router::get('/', 'App\Controller\Websocket\Wss'); }); ```