TP项目启用websocket聊天功能
须知
- swoole不支持windows安装,没有windows扩展
- WebSocket 在线测试(可测本地wss连接) websocket在线测试
- 建议gateway只负责给终端发信,不参与逻辑部分
- 后台负责所有的收信+发信安排,可以方便地获取用户好友关系、上下线状态管理、消息缓存、已读未读
整体安装顺序
- 【任务-1】在TP项目.env配置中添加
# 聊天室-websocket长连接 [WORKER] NAME = businessWorker PORT = 8282 COUNT = 2 START_PORT = 2900 REGISTER_ADDRESS = 127.0.0.1:1236 lAN_IP = 127.0.0.1 REGISTER_DEPLOY = true
- 【任务0】nginx服务器配置接口站点进行wss转发ws,重启php+nginx:
server { location /wss { proxy_pass http://127.0.0.1:8282; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; } }
- 【任务1】 Linux下composer安装gatewayclient和gateway-worker
1)宝塔中安装php8 + php8专用的swoole4、fileinfo、redis
2)cd到后台根目录,使用指定php版本执行composer安装以上依赖 - 【任务2】部署GatewayWorker启动器到tp项目
- 【任务3】部署GatewayWorker逻辑处理器到tp项目
- 【任务4】手动启动worker监听服务
- 【任务5】前端连接,开始聊天
启动wss服务 / 停止wss服务
Linux环境
启动方法
cd /path/of/project/
/www/server/php/80/bin/php start.php start -d
停止方法
cd /path/of/project/
/www/server/php/80/bin/php start.php stop
Windows环境
启动方法
双击打开start_for_win.bat
停止方法
切换到以上窗口,Ctrl+C,会问y/n,输入y回车即可;
没反应的话,按多几次
其他问题
怎么修改wss端口?
修改\app\worker\start_gateway.php的“gateway 进程” + nginx转发地址端口号
连接顺序示例
- 前端指定wss服务器地址 wss://xx.com/wss
- 前端连接wss服务器
this.wss = uni.connectSocket({ url: this.wss_url, success: () => { console.log('>> wssStore() > connect() > success()') }, fail: (e) => { console.log('>> wssStore() > connect() > fail()') console.log('>> ', JSON.stringify(e)) }, complete: ()=> { console.log('>> wssStore() > connect() > complete()') } })
- 前端连接wss成功后,触发后台\app\worker\Events.php::onConnect($client_id)
这时后台应该考虑通过gateway通知此终端(前端)进行init操作,// 初次连接 - 初始化命令 clog('>> 初始化命令 > 开始通知'); Gateway::sendToClient($client_id, json_encode(array( 'type' => 'init', 'client_id' => $client_id ))); clog('>> 初始化命令 > 完成通知');
- 前端收到wss来信,命令=init,这时应该向tp后台接口回信,提交当前用户ID+wss分配的终端ID进行绑定:
// 记录终端id this.client_id = message.client_id || null // 通知后台uid + client_id绑定 let bInfo = { user_id: this.user_id, client_id: this.client_id } let bindOK = await request.post({ url: '后台绑定接口', data: bInfo }) // 绑定成功 if (bindOK) { this.isBind = true // 通知服务器 发送当前用户的 离线未拉取信息 this.let_server_send_my_un_downloaded_message() } else { // 绑定失败 this.isBind = false }
- TP后台收到前端通知,在gateway层面绑定当前终端与当前用户,并通知好友关于此人的上线状态,并更新用户的登录记录
/** * 绑定用户ID和终端ID */ public static function userBinding ($user_id, $client_id) { // 如果当前ID在线,将其他地方登陆挤兑下线 if(Gateway::isUidOnline($user_id)){ // 通过gateway向已连接的指定终端推送指令 - 命令其下线 wsSendMsg($user_id,'offline',['id'=>$user_id,'client_id'=>$client_id]); } // 绑定人+设备 Gateway::bindUid($client_id, $user_id); // 更新登录信息 // 获取好友 $friends = self::get_friends_uids_by_user_id($user_id); // 通知好友,有人上线了 foreach ($friends as $oneUid) { wsSendMsg($oneUid,'isOnline',['id'=>$user_id,'is_online'=>1]); } }
- 前端A发信息给B
1)A把信息发给后台接口(不是直接通过wss发信),指明发给B
2)后台写入数据库,判断B是否在线
在线)通过gateway给B发信
离线)无动作... - 前端B接收发信息给A:如上,A在线的话就收到gateway发来的信息,不在线就下次上线再一起收信(未读)
- 前端不想聊了,分两步操作:
1)主动通知后台“我要下线”,后台可以更新下线时间,再找出此人的好友列表,并通知大家此人已下线;// 获取好友,逐一通知 $friends = self::get_friends_uids_by_user_id($user_id); foreach ($friends as $oneUid) { // 通过uid去发信,不管在不在线 wsSendMsg($oneUid, 'isOffline', ['id'=>$user_id, 'is_online'=>0]); }
2)关闭wss连接,触发后台\app\worker\Events.php::onClose($client_id),这时后台可以考虑通过gateway释放此终端的占用资源:Gateway::closeClient($client_id) - 核心业务已完成
【任务1】 Linux下composer安装gatewayclient和gateway-worker
参考
laravel+workerman/gateway-worker 从安装到运行
https://blog.csdn.net/Dong_Alex/article/details/105902207
本地开发路径
/home/king/tmp/top-backend/server
目标命令,先不执行:
composer require workerman/gatewayclient
composer require workerman/gateway-worker
直接运行报错信息:
[king@localhost server]$ composer require workerman/gatewayclient
./composer.json has been updated
Running composer update workerman/gatewayclient
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Root composer.json requires php >=8.0 but your php version (7.3.31) does not satisfy that requirement.
Problem 2
- overtrue/wechat is locked to version 5.7.1 and an update of this package was not requested.
- overtrue/wechat 5.7.1 requires php >=7.4 -> your php version (7.3.31) does not satisfy that requirement.
Problem 3
- topthink/think-swoole is locked to version v3.1.3 and an update of this package was not requested.
- topthink/think-swoole v3.1.3 requires ext-swoole >=4.4.8 -> it is missing from your system. Install or enable PHP's swoole extension.
To enable extensions, verify that they are enabled in your .ini files:
- /www/