目录
一、安装扩展
cd到项目下进行扩展安装:
composer require topthink/think-worker
扩展安装后根据TP官方提供的文档进行启动
Workerman · ThinkPHP6.0完全开发手册 · 看云
注意事项:扩展安装好后会在 项目根目录 下面新增一个文本文件,用作启动websocket(很方便),测试开启直接双击即可
1.将两行命令加入文本文件
php think worker:server
pause
2.更改文本文件后缀
Socket.bat
3.扩展安装成功后会在项目config文件下生成两个文件,配置只需要更改worker_server.php
二、websocket配置
1.worker_server.php
重要的配置要更改这两个地方:
端口:
'port' => 2345, //
woker文件:
'worker_class' => 'app\user\controller\Worker',
自定义Workerman服务类名(独立的woker控制器路径)
注意事项分享:数据库形式
2.新建控制器Worker(名字随意)
<?php
declare(strict_types=1);
namespace app\user\controller;
use think\worker\Server;
class Worker extends Server
{
/**websocket */
protected $socket = 'websocket://0.0.0.0:2345';
/**定义用户组*/
protected $uidArr = [];
/*
@method 发送消息
@param data 数据
*/
public function onMessage($connection, $data)
{
/**对接收消息做json处理*/
$rest = json_decode($data);
/**用户连接成功后向后端发送 type=bind,uid=当前连接用户uid 的绑定请求 */
if ($rest->type == 'bind' && !isset($connection->uid)) {
/**将请求用户id存在用户组中 */
$connection->uid = $rest->uid;
$this->uidArr[$connection->uid] = $connection;
echo 'user:' . $rest->uid . 'bind';
}
/**群聊 */
if ($rest->type == "text") {
/**模型实例*/
/**这里做数据库获取该群有哪些成员的操作,这里我用测试数据 */
$group_user_ids_arr = [1,2,3];
/**这里做将信息存入数据库并获取信息id的逻辑 */
$saveMsg = $msgModel->insertGetId([
'from_user_id' => $rest->from_user_id, //来自
'to_gid' => $rest->to_gid, //给谁
'from_nickname' => $rest->from_nickname,//来自人昵称
'from_headimg' => $rest->from_headimg, //来自人头像
'datetime' => $rest->datetime, //消息时间
'msg' => $rest->msg, //消息内容
'type' => $rest->type //消息类型:文本...
]);
/**将新消息id存入发送数据中方便做后续撤回等操作*/
/**解析信息 */
$newData = json_decode($data, true);
/**赋值信息数据自增id */
$newData['id'] = $saveMsg;
/**针对群用户发消息 */
foreach ($group_user_ids_arr as $key => $value) {
/**针对在线用户并且!!排除自己
(前端配合将消息push到当前发送消息的用户)!!发消息 */
if (isset($this->uidArr[$value]) && $value != $rest->from_user_id) {
$conn = $this->uidArr[$value];
/**发送信息 */
$conn->send(json_encode($newData));
//前端回调后要判断当前接收消息的群id将消息放进对应的群,不然会出现用户在线不管在哪个群都会收到消息的问题!!!
}
}
}
}
/**
* 当连接建立时触发的回调函数
* @param $connection
*/
public function onConnect($connection)
{
print_r('连接成功');
}
/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
print_r('用户断开了链接!');
}
/**
* 当客户端的连接上发生错误时触发
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg)
{
echo "error $code $msg\n";
}
/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{
}
}
总结
此方法需要前端配合判断当前接收信息的群id将消息放进对应的群,不然会出现用户在线不管在哪个群都会收到消息的问题!!!