no message

This commit is contained in:
kuaifan 2025-04-18 14:01:33 +08:00
parent 5aed9ce29e
commit b3b7589db3
8 changed files with 74 additions and 38 deletions

1
.gitignore vendored
View File

@ -29,3 +29,4 @@ vars.yaml
laravels.conf laravels.conf
laravels.pid laravels.pid
README_LOCAL.md README_LOCAL.md
dootask.lock

View File

@ -22,40 +22,64 @@ class SyncUserMsgToZincSearch extends Command
protected $signature = 'zinc:sync-user-msg {--f} {--i} {--c} {--batch=1000}'; protected $signature = 'zinc:sync-user-msg {--f} {--i} {--c} {--batch=1000}';
protected $description = '同步聊天会话用户和消息到 ZincSearch'; protected $description = '同步聊天会话用户和消息到 ZincSearch';
/**
* 缓存锁实例
*/
protected $lock;
/** /**
* @return int * @return int
*/ */
public function handle(): int public function handle(): int
{ {
// 注册信号处理器仅在支持pcntl扩展的环境下
if (extension_loaded('pcntl')) {
pcntl_async_signals(true); // 启用异步信号处理
pcntl_signal(SIGINT, [$this, 'handleSignal']); // Ctrl+C
pcntl_signal(SIGTERM, [$this, 'handleSignal']); // kill
}
// 使用缓存锁确保一次只能运行一个实例 // 使用缓存锁确保一次只能运行一个实例
$lock = Cache::lock('zinc:sync-user-msg', 3600 * 6); // 锁定6小时 $this->lock = Cache::lock('zinc:sync-user-msg', 3600 * 6); // 锁定6小时
if (!$lock->get()) { if (!$this->lock->get()) {
$this->error('命令已在运行中,请等待当前实例完成'); $this->error('命令已在运行中,请等待当前实例完成');
return 1; return 1;
} }
try { // 清除索引
// 清除索引 if ($this->option('c')) {
if ($this->option('c')) { $this->info('清除索引...');
$this->info('清除索引...'); ZincSearchKeyValue::clear();
ZincSearchKeyValue::clear(); ZincSearchDialogMsg::clear();
ZincSearchDialogMsg::clear(); $this->info("索引删除成功");
$this->info("索引删除成功"); $this->lock?->release();
return 0;
}
$this->info('开始同步聊天数据...');
// 同步消息数据
$this->syncDialogMsgs();
// 完成
$this->info("\n同步完成");
return 0; return 0;
} finally {
// 确保无论如何都会释放锁
$lock->release();
} }
$this->info('开始同步聊天数据...');
// 同步消息数据
$this->syncDialogMsgs();
// 完成
$this->info("\n同步完成");
$this->lock?->release();
return 0;
}
/**
* 处理终端信号
*
* @param int $signal
* @return void
*/
public function handleSignal(int $signal): void
{
// 释放锁
if ($this->lock) {
$this->lock->release();
}
exit(0);
} }
/** /**
@ -65,16 +89,23 @@ class SyncUserMsgToZincSearch extends Command
*/ */
private function syncDialogMsgs(): void private function syncDialogMsgs(): void
{ {
$this->info("\n同步消息数据...");
// 获取上次同步的最后ID // 获取上次同步的最后ID
$lastKey = "sync:dialogUserMsgLastId"; $lastKey = "sync:dialogUserMsgLastId";
$lastId = $this->option('i') ? intval(ZincSearchKeyValue::get($lastKey, 0)) : 0; $lastId = $this->option('i') ? intval(ZincSearchKeyValue::get($lastKey, 0)) : 0;
if ($lastId > 0) {
$this->info("\n同步消息数据({$lastId}...");
} else {
$this->info("\n同步消息数据...");
}
$num = 0; $num = 0;
$count = WebSocketDialogMsg::where('id', '>', $lastId)->count(); $count = WebSocketDialogMsg::where('id', '>', $lastId)->count();
$batchSize = $this->option('batch'); $batchSize = $this->option('batch');
$total = 0;
$lastNum = 0;
do { do {
// 获取一批 // 获取一批
$dialogMsgs = WebSocketDialogMsg::where('id', '>', $lastId) $dialogMsgs = WebSocketDialogMsg::where('id', '>', $lastId)
@ -88,10 +119,14 @@ class SyncUserMsgToZincSearch extends Command
$num += count($dialogMsgs); $num += count($dialogMsgs);
$progress = round($num / $count * 100, 2); $progress = round($num / $count * 100, 2);
$this->info("{$num}/{$count} ({$progress}%) 正在同步消息ID {$lastId} ~ {$dialogMsgs->last()->id}"); if ($progress < 100) {
$progress = number_format($progress, 2);
}
$this->info("{$num}/{$count} ({$progress}%) 正在同步消息ID {$dialogMsgs->first()->id} ~ {$dialogMsgs->last()->id} ({$total}|{$lastNum})");
// 同步数据 // 同步数据
ZincSearchDialogMsg::batchSync($dialogMsgs); $lastNum = ZincSearchDialogMsg::batchSync($dialogMsgs);
$total += $lastNum;
// 更新最后ID // 更新最后ID
$lastId = $dialogMsgs->last()->id; $lastId = $dialogMsgs->last()->id;

View File

@ -23,7 +23,7 @@ use App\Tasks\AutoArchivedTask;
use App\Tasks\DeleteBotMsgTask; use App\Tasks\DeleteBotMsgTask;
use App\Tasks\CheckinRemindTask; use App\Tasks\CheckinRemindTask;
use App\Tasks\CloseMeetingRoomTask; use App\Tasks\CloseMeetingRoomTask;
use App\Tasks\ElasticSearchSyncTask; use App\Tasks\ZincSearchSyncTask;
use App\Tasks\UnclaimedTaskRemindTask; use App\Tasks\UnclaimedTaskRemindTask;
use Hhxsv5\LaravelS\Swoole\Task\Task; use Hhxsv5\LaravelS\Swoole\Task\Task;
use Laravolt\Avatar\Avatar; use Laravolt\Avatar\Avatar;
@ -259,8 +259,8 @@ class IndexController extends InvokeController
Task::deliver(new UnclaimedTaskRemindTask()); Task::deliver(new UnclaimedTaskRemindTask());
// 关闭会议室 // 关闭会议室
Task::deliver(new CloseMeetingRoomTask()); Task::deliver(new CloseMeetingRoomTask());
// ElasticSearch 同步 // ZincSearch 同步
Task::deliver(new ElasticSearchSyncTask()); Task::deliver(new ZincSearchSyncTask());
return "success"; return "success";
} }

View File

@ -387,7 +387,7 @@ class ZincSearchDialogMsg
} }
if ($dialogMsg->bot) { if ($dialogMsg->bot) {
// 如果是机器人消息,跳过 // 如果是机器人消息,跳过
return true; continue;
} }
/** @var WebSocketDialogUser $dialogUser */ /** @var WebSocketDialogUser $dialogUser */
foreach ($userDialogs[$dialogMsg->dialog_id] as $dialogUser) { foreach ($userDialogs[$dialogMsg->dialog_id] as $dialogUser) {

6
cmd
View File

@ -457,8 +457,6 @@ if [ $# -gt 0 ]; then
sleep 3 sleep 3
fi fi
done done
# 设置ES索引后缀
env_set ES_INDEX_SUFFIX "$(rand_string 6)"
# 启动容器 # 启动容器
[[ "$(arg_get port)" -gt 0 ]] && env_set APP_PORT "$(arg_get port)" [[ "$(arg_get port)" -gt 0 ]] && env_set APP_PORT "$(arg_get port)"
$COMPOSE up php -d $COMPOSE up php -d
@ -479,7 +477,7 @@ if [ $# -gt 0 ]; then
# 数据库迁移 # 数据库迁移
run_exec php "php artisan migrate --seed" run_exec php "php artisan migrate --seed"
# 启动其他容器 # 启动其他容器
$COMPOSE up -d $COMPOSE up -d --remove-orphans
success "安装完成" success "安装完成"
info "地址: http://${GreenBG}127.0.0.1:$(env_get APP_PORT)${Font}" info "地址: http://${GreenBG}127.0.0.1:$(env_get APP_PORT)${Font}"
# 设置初始化密码 # 设置初始化密码
@ -504,7 +502,7 @@ if [ $# -gt 0 ]; then
run_exec php "php artisan migrate" run_exec php "php artisan migrate"
run_exec nginx "nginx -s reload" run_exec nginx "nginx -s reload"
restart_php restart_php
$COMPOSE up -d $COMPOSE up -d --remove-orphans
elif [[ "$1" == "uninstall" ]]; then elif [[ "$1" == "uninstall" ]]; then
shift 1 shift 1
read -rp "确定要卸载(含:删除容器、数据库、日志)吗?(Y/n): " uninstall read -rp "确定要卸载(含:删除容器、数据库、日志)吗?(Y/n): " uninstall

View File

@ -111,6 +111,7 @@ services:
KK_OFFICE_PREVIEW_SWITCH_DISABLED: true KK_OFFICE_PREVIEW_SWITCH_DISABLED: true
KK_FILE_UPLOAD_ENABLED: true KK_FILE_UPLOAD_ENABLED: true
KK_MEDIA: "mp3,wav,mp4,mov,avi,wmv" KK_MEDIA: "mp3,wav,mp4,mov,avi,wmv"
ES_JAVA_OPTS: "-Xmx1g"
networks: networks:
extnetwork: extnetwork:
ipv4_address: "${APP_IPPR}.7" ipv4_address: "${APP_IPPR}.7"
@ -229,6 +230,11 @@ services:
ZINC_DATA_PATH: "/data" ZINC_DATA_PATH: "/data"
ZINC_FIRST_ADMIN_USER: "${DB_USERNAME}" ZINC_FIRST_ADMIN_USER: "${DB_USERNAME}"
ZINC_FIRST_ADMIN_PASSWORD: "${DB_PASSWORD}" ZINC_FIRST_ADMIN_PASSWORD: "${DB_PASSWORD}"
deploy:
resources:
limits:
cpus: '1'
memory: 1G
networks: networks:
extnetwork: extnetwork:
ipv4_address: "${APP_IPPR}.15" ipv4_address: "${APP_IPPR}.15"

View File

@ -1,2 +0,0 @@
cluster.name: "docker-cluster"
network.host: 0.0.0.0

View File

@ -1,2 +0,0 @@
*
!.gitignore