首页 / 跨境电商轻量软件 / 实操指南:搭建站内信与通知接口的5个通信方案

实操指南:搭建站内信与通知接口的5个通信方案

实操指南:搭建站内信与通知接口的5个通信方案(基于WordPress开发)

引言:为什么站内信与通知系统如此重要

在当今的网站和应用程序中,站内信与通知系统已成为用户交互的核心组成部分。无论是电商平台的订单状态更新、社交媒体的互动提醒,还是企业系统的任务通知,一个高效、可靠的通信机制都能显著提升用户体验和参与度。

对于WordPress开发者而言,构建这样的系统既充满挑战也蕴含机遇。WordPress作为全球最流行的内容管理系统,其庞大的插件生态和灵活的架构为我们提供了多种实现方案。本文将深入探讨五种基于WordPress的通信方案,从简单到复杂,帮助行业新人和程序员选择最适合自己项目的解决方案。

方案一:基于WordPress原生功能的简易方案

1.1 使用WordPress评论系统作为基础

WordPress自带的评论系统实际上是一个成熟的用户间通信框架。我们可以巧妙地利用这个系统构建简单的站内信功能:

/**
 * 将评论系统改造为站内信功能
 */
class WP_Message_System {
    
    public function __construct() {
        // 注册自定义帖子类型作为消息容器
        add_action('init', array($this, 'register_message_post_type'));
        
        // 修改评论提交逻辑
        add_filter('preprocess_comment', array($this, 'process_private_message'));
        
        // 添加消息查看权限控制
        add_filter('comments_clauses', array($this, 'filter_private_messages'));
    }
    
    public function register_message_post_type() {
        $args = array(
            'public' => false,
            'show_ui' => false,
            'supports' => array('title', 'comments'),
            'labels' => array(
                'name' => '站内信',
                'singular_name' => '站内信'
            )
        );
        register_post_type('private_message', $args);
    }
    
    public function process_private_message($commentdata) {
        // 检查是否为私信
        if (isset($_POST['is_private_message']) && $_POST['is_private_message'] == '1') {
            $commentdata['comment_post_ID'] = $this->get_or_create_message_thread(
                $_POST['recipient_id'],
                get_current_user_id()
            );
            $commentdata['comment_approved'] = 1;
        }
        return $commentdata;
    }
    
    private function get_or_create_message_thread($user1_id, $user2_id) {
        // 查找或创建消息线程
        $thread_id = $this->find_existing_thread($user1_id, $user2_id);
        
        if (!$thread_id) {
            $thread_id = wp_insert_post(array(
                'post_title' => sprintf('用户%d与用户%d的对话', $user1_id, $user2_id),
                'post_type' => 'private_message',
                'post_status' => 'private'
            ));
            
            // 保存参与者信息
            update_post_meta($thread_id, '_participants', array($user1_id, $user2_id));
        }
        
        return $thread_id;
    }
}

1.2 利用用户元数据存储通知

对于简单的通知系统,我们可以使用WordPress的用户元数据功能:

/**
 * 基于用户元数据的通知系统
 */
class WP_Notification_System {
    
    public function add_notification($user_id, $message, $type = 'info', $data = array()) {
        $notifications = get_user_meta($user_id, '_user_notifications', true);
        
        if (!is_array($notifications)) {
            $notifications = array();
        }
        
        $notification = array(
            'id' => uniqid(),
            'message' => sanitize_text_field($message),
            'type' => $type,
            'data' => $data,
            'timestamp' => current_time('timestamp'),
            'read' => false
        );
        
        array_unshift($notifications, $notification);
        
        // 只保留最近的50条通知
        if (count($notifications) > 50) {
            $notifications = array_slice($notifications, 0, 50);
        }
        
        update_user_meta($user_id, '_user_notifications', $notifications);
        
        return $notification['id'];
    }
    
    public function get_unread_count($user_id) {
        $notifications = get_user_meta($user_id, '_user_notifications', true);
        
        if (!is_array($notifications)) {
            return 0;
        }
        
        $unread = 0;
        foreach ($notifications as $notification) {
            if (!$notification['read']) {
                $unread++;
            }
        }
        
        return $unread;
    }
}

优点:实现简单,无需额外数据库表,适合小型网站
缺点:性能随数据量增加而下降,缺乏高级功能

方案二:基于自定义数据库表的完整方案

2.1 设计消息与通知数据库表

对于中大型网站,我们需要更专业的数据库设计:

/**
 * 创建消息系统数据库表
 */
class WP_Message_DB {
    
    public static function create_tables() {
        global $wpdb;
        
        $charset_collate = $wpdb->get_charset_collate();
        
        // 消息线程表
        $threads_table = $wpdb->prefix . 'message_threads';
        $threads_sql = "CREATE TABLE $threads_table (
            thread_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            subject VARCHAR(255) DEFAULT '',
            last_message_time DATETIME DEFAULT '0000-00-00 00:00:00',
            created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (thread_id)
        ) $charset_collate;";
        
        // 线程参与者表
        $participants_table = $wpdb->prefix . 'message_participants';
        $participants_sql = "CREATE TABLE $participants_table (
            participant_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            thread_id BIGINT(20) UNSIGNED NOT NULL,
            user_id BIGINT(20) UNSIGNED NOT NULL,
            last_read_time DATETIME DEFAULT '0000-00-00 00:00:00',
            deleted TINYINT(1) DEFAULT 0,
            PRIMARY KEY (participant_id),
            KEY thread_user (thread_id, user_id)
        ) $charset_collate;";
        
        // 消息表
        $messages_table = $wpdb->prefix . 'messages';
        $messages_sql = "CREATE TABLE $messages_table (
            message_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            thread_id BIGINT(20) UNSIGNED NOT NULL,
            sender_id BIGINT(20) UNSIGNED NOT NULL,
            message_content LONGTEXT NOT NULL,
            message_time DATETIME DEFAULT CURRENT_TIMESTAMP,
            is_read TINYINT(1) DEFAULT 0,
            PRIMARY KEY (message_id),
            KEY thread_time (thread_id, message_time)
        ) $charset_collate;";
        
        // 通知表
        $notifications_table = $wpdb->prefix . 'user_notifications';
        $notifications_sql = "CREATE TABLE $notifications_table (
            notification_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            user_id BIGINT(20) UNSIGNED NOT NULL,
            notification_type VARCHAR(50) NOT NULL,
            title VARCHAR(255) NOT NULL,
            content TEXT NOT NULL,
            related_id BIGINT(20) UNSIGNED DEFAULT NULL,
            is_read TINYINT(1) DEFAULT 0,
            created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
            expires_time DATETIME DEFAULT NULL,
            PRIMARY KEY (notification_id),
            KEY user_read (user_id, is_read, created_time)
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($threads_sql);
        dbDelta($participants_sql);
        dbDelta($messages_sql);
        dbDelta($notifications_sql);
    }
}

2.2 实现消息系统核心功能

/**
 * 完整的消息系统实现
 */
class Advanced_Message_System {
    
    private $db;
    
    public function __construct() {
        global $wpdb;
        $this->db = $wpdb;
        
        // 初始化数据库表
        register_activation_hook(__FILE__, array('WP_Message_DB', 'create_tables'));
        
        // 添加REST API端点
        add_action('rest_api_init', array($this, 'register_rest_routes'));
    }
    
    public function send_message($sender_id, $recipient_ids, $content, $subject = '') {
        // 创建或获取消息线程
        $thread_id = $this->get_or_create_thread($sender_id, $recipient_ids, $subject);
        
        // 插入消息
        $this->db->insert(
            $this->db->prefix . 'messages',
            array(
                'thread_id' => $thread_id,
                'sender_id' => $sender_id,
                'message_content' => wp_kses_post($content),
                'message_time' => current_time('mysql')
            ),
            array('%d', '%d', '%s', '%s')
        );
        
        $message_id = $this->db->insert_id;
        
        // 更新线程最后消息时间
        $this->db->update(
            $this->db->prefix . 'message_threads',
            array('last_message_time' => current_time('mysql')),
            array('thread_id' => $thread_id),
            array('%s'),
            array('%d')
        );
        
        // 为接收者创建通知
        foreach ($recipient_ids as $recipient_id) {
            if ($recipient_id != $sender_id) {
                $this->create_notification(
                    $recipient_id,
                    'new_message',
                    '新消息',
                    sprintf('您收到来自%s的新消息', get_userdata($sender_id)->display_name),
                    $thread_id
                );
            }
        }
        
        return array(
            'thread_id' => $thread_id,
            'message_id' => $message_id
        );
    }
    
    public function create_notification($user_id, $type, $title, $content, $related_id = null) {
        $this->db->insert(
            $this->db->prefix . 'user_notifications',
            array(
                'user_id' => $user_id,
                'notification_type' => $type,
                'title' => sanitize_text_field($title),
                'content' => sanitize_text_field($content),
                'related_id' => $related_id,
                'created_time' => current_time('mysql')
            ),
            array('%d', '%s', '%s', '%s', '%d', '%s')
        );
        
        return $this->db->insert_id;
    }
}

优点:性能优秀,功能完整,支持大量数据
缺点:实现复杂,需要维护数据库结构

方案三:基于WebSocket的实时通信方案

3.1 搭建WebSocket服务器

对于需要实时通信的应用,WebSocket是理想选择:

/**
 * WebSocket服务器实现(使用Ratchet库)
 * 需要Composer安装Ratchet: composer require cboden/ratchet
 */
class RealTime_Message_Server {
    
    private $clients;
    private $user_connections;
    
    public function __construct() {
        $this->clients = new SplObjectStorage;
        $this->user_connections = array();
    }
    
    public function onOpen(RatchetConnectionInterface $conn) {
        $this->clients->attach($conn);
        
        // 解析连接参数获取用户ID
        $query_string = $conn->httpRequest->getUri()->getQuery();
        parse_str($query_string, $query_params);
        
        if (isset($query_params['user_id']) && isset($query_params['token'])) {
            if ($this->verify_user_token($query_params['user_id'], $query_params['token'])) {
                $user_id = intval($query_params['user_id']);
                $this->user_connections[$user_id] = $conn;
                
                $conn->send(json_encode(array(
                    'type' => 'connection_established',
                    'user_id' => $user_id,
                    'timestamp' => time()
                )));
            }
        }
    }
    
    public function onMessage(RatchetConnectionInterface $from, $msg) {
        $data = json_decode($msg, true);
        
        if (!$data || !isset($data['type'])) {
            return;
        }
        
        switch ($data['type']) {
            case 'private_message':
                $this->handle_private_message($from, $data);
                break;
                
            case 'typing_indicator':
                $this->handle_typing_indicator($from, $data);
                break;
                
            case 'read_receipt':
                $this->handle_read_receipt($from, $data);
                break;
        }
    }
    
    private function handle_private_message($from, $data) {
        // 验证发送者
        $sender_id = $this->get_user_id_by_connection($from);
        
        if (!$sender_id || !isset($data['recipient_id']) || !isset($data['content'])) {
            return;
        }
        
        $recipient_id = intval($data['recipient_id']);
        
        // 保存到数据库
        $message_system = new Advanced_Message_System();
        $result = $message_system->send_message(
            $sender_id,
            array($recipient_id),
            $data['content']
        );
        
        // 如果接收者在线,实时推送
        if (isset($this->user_connections[$recipient_id])) {
            $recipient_conn = $this->user_connections[$recipient_id];
            
            $recipient_conn->send(json_encode(array(
                'type' => 'new_message',
                'message_id' => $result['message_id'],
                'thread_id' => $result['thread_id'],
                'sender_id' => $sender_id,
                'content' => $data['content'],
                'timestamp' => time()
            )));
        }
        
        // 发送回执给发送者
        $from->send(json_encode(array(
            'type' => 'message_sent',
            'message_id' => $result['message_id'],
            'timestamp' => time()
        )));
    }
}

3.2 WordPress与WebSocket集成

/**
 * WordPress端WebSocket客户端集成
 */
class WP_WebSocket_Client {
    
    public function __construct() {
        // 添加WebSocket脚本
        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
        
        // 生成用户认证令牌
        add_filter('wp_generate_auth_cookie', array($this, 'generate_ws_token'), 10, 5);
    }
    
    public function enqueue_scripts() {
        if (is_user_logged_in()) {
            wp_enqueue_script('websocket-client', 
                plugins_url('js/websocket-client.js', __FILE__),
                array('jquery'), '1.0', true);
            
            $current_user = wp_get_current_user();
            
            wp_localize_script('websocket-client', 'ws_config', array(
                'ws_url' => 'ws://your-domain.com:8080',
                'user_id' => $current_user->ID,
                'token' => $this->get_user_ws_token($current_user->ID),
                'ajax_url' => admin_url('admin-ajax.php')
            ));
        }
    }
    
    public function get_user_ws_token($user_id) {
        $token = get_user_meta($user_id, '_ws_auth_token', true);
        
        if (!$token) {
            $token = wp_generate_password(32, false);
            update_user_meta($user_id, '_ws_auth_token', $token);
        }
        
        return $token;
    }
}

优点:真正的实时通信,用户体验优秀
缺点:服务器要求高,实现复杂,需要SSL证书

方案四:基于REST API的微服务架构

4.1 设计消息微服务

对于大型分布式系统,微服务架构是更好的选择:

/**
 * 消息微服务REST API
 */
class Message_Microservice_API {
    
    public function register_rest_routes() {
        register_rest_route('message-service/v1', '/threads', array(
            array(
                'methods' => 'GET',
                'callback' => array($this, 'get_user_threads'),
                'permission_callback' => array($this, 'check_user_permission')
            ),
            array(
                'methods' => 'POST',
                'callback' => array($this, 'create_thread'),
                'permission_callback' => array($this, 'check_user_permission')
            )
        ));
        
        register_rest_route('message-service/v1', '/threads/(?P<thread_id>d+)/messages', array(
            array(
                'methods' => 'GET',
                'callback' => array($this, 'get_thread_messages'),
                'permission_callback' => array($this, 'check_thread_permission')
            ),
            array(
                'methods' => 'POST',
                'callback' => array($this, 'send_message'),
                'permission_callback' => array($this, 'check_thread_permission')
            )
        ));
        
        register_rest_route('notification-service/v1', '/notifications', array(
            array(
                'methods' => 'GET',
                'callback' => array($this, 'get_user_notifications'),
                'permission_callback' => array($this, 'check_user_permission')
            )
        ));
    }
    
    public function send_message($request) {
        $thread_id = $request->get_param('thread_id');
        $user_id = get_current_user_id();
        
        $parameters = $request->get_json_params();
        
        // 验证消息内容
        if (empty($parameters['content'])) {
            return new WP_Error('invalid_content', '消息内容不能为空', array('status' => 400));
        }
        
        // 保存消息
        $message_system = new Advanced_Message_System();
        $result = $message_system->send_message(
            $user_id,
            $this->get_thread_recipients($thread_id, $user_id),
            $parameters['content']
        );
        
        // 触发消息发送事件
        do_action('message_sent', $result['message_id'], $thread_id, $user_id);
        
        // 返回标准化响应
        return rest_ensure_response(array(
            'success' => true,
            'data' => array(
                'message_id' => $result['message_id'],
                'thread_id' => $thread_id,
                'sent_at' => current_time('mysql')
            )
        ));
    }
    
    public function get_user_notifications($request) {
        $user_id = get_current_user_id();
        $page = max(1, intval($request->get_param('page')));
        $per_page = min(50, intval($request->get_param('per_page') ?: 20));
        $offset = ($page - 1) * $per_page;
        
        global $wpdb;
        
        $notifications = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}user_notifications 
             WHERE user_id = %d 
             ORDER BY created_time DESC 
             LIMIT %d OFFSET %d",
            $user_id, $per_page, $offset
        ));
        
        $total = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}user_notifications 
             WHERE user_id = %d",
            $user_id
        ));
        
        // 格式化响应数据
        $formatted_notifications = array_map(function($notification) {
            return array(
                'id' => intval($notification->notification_id),
                'type' => $notification->notification_type,
                'title' => $notification->title,
                'content' => $notification->content,
                'related_id' => $notification->related_id ? intval($notification->related_id) : null,
                'is_read' => (bool)$notification->is_read,
                'created_at' => $notification->created_time,
                'expires_at' => $notification->expires_time
            );
        }, $notifications);
        
        return rest_ensure_response(array(
            'data' => $formatted_notifications,
            'pagination' => array(
                'page' => $page,
                'per_page' => $per_page,
                'total' => intval($total),
                'total_pages' => ceil($total / $per_page)
            )
        ));
    }
}

4.2 消息队列与异步处理

/**
 * 基于Redis的消息队列系统
 */
class Message_Queue_System {
    
    private $redis;
    private $queue_name = 'wp_message_queue';
    
    public function __construct() {
        if (class_exists('Redis')) {
            $this->redis = new Redis();
            $this->connect_redis();
        }
    }
    
    private function connect_redis() {
        try {
            $this->redis->connect('127.0.0.1', 6379, 2.5);
            $this->redis->auth('your_redis_password');
            
            // 测试连接
            if (!$this->redis->ping()) {
                error_log('Redis连接失败');
                $this->redis = null;
            }
        } catch (Exception $e) {
            error_log('Redis连接异常: ' . $e->getMessage());
            $this->redis = null;
        }
    }
    
    public function push_to_queue($job_type, $data) {
        if (!$this->redis) {
            // 降级处理:直接执行
            return $this->process_job($job_type, $data);
        }
        
        $job = array(
            'id' => uniqid(),
            'type' => $job_type,
            'data' => $data,
            'created_at' => time(),
            'attempts' => 0
        );
        
        $this->redis->lPush($this->queue_name, json_encode($job));
        
        return $job['id'];
    }
    
    public function process_queue() {
        if (!$this->redis) {
            return;
        }
        
        $job_json = $this->redis->rPop($this->queue_name);
        
        if ($job_json) {
            $job = json_decode($job_json, true);
            $this->process_job($job['type'], $job['data']);
        }
    }
    
    private function process_job($type, $data) {
        switch ($type) {
            case 'send_notification':
                $this->send_bulk_notification($data);
                break;
                
            case 'process_message':
                $this->process_message_delivery($data);
                break;
                
            case 'cleanup_old_data':
                $this->cleanup_old_messages($data);
                break;
        }
    }
    
    private function send_bulk_notification($data) {
        // 批量发送通知给多个用户
        $user_ids = $data['user_ids'];
        $notification_data = $data['notification'];
        
        foreach ($user_ids as $user_id) {
            $notification_system = new Advanced_Message_System();
            $notification_system->create_notification(
                $user_id,
                $notification_data['type'],
                $notification_data['title'],
                $notification_data['content'],
                $notification_data['related_id'] ?? null
            );
        }
    }
}

优点:高可扩展性,易于维护,支持分布式部署
缺点:架构复杂,需要多个服务协同工作

方案五:混合方案与最佳实践

5.1 智能混合通信策略

/**
 * 智能混合通信系统
 * 根据场景自动选择最佳通信方式
 */
class Hybrid_Communication_System {
    
    private $strategies = array();
    
    public function __construct() {
        // 注册不同通信策略
        $this->strategies = array(
            'immediate' => new Immediate_Delivery_Strategy(),
            'batch' => new Batch_Delivery_Strategy(),
            'scheduled' => new Scheduled_Delivery_Strategy(),
            'priority' => new Priority_Delivery_Strategy()
        );
        
        // 监控系统负载
        add_action('wp_loaded', array($this, 'monitor_system_load'));
    }
    
    public function send_message($message_data) {
        // 根据消息类型和系统状态选择策略
        $strategy = $this->select_delivery_strategy($message_data);
        
        return $strategy->deliver($message_data);
    }
    
    private function select_delivery_strategy($message_data) {
        $message_type = $message_data['type'] ?? 'normal';
        $priority = $message_data['priority'] ?? 'medium';
        $recipient_count = count($message_data['recipients'] ?? array());
        
        // 实时消息:使用WebSocket
        if ($message_type === 'real_time' && $this->is_websocket_available()) {
            return $this->strategies['immediate'];
        }
        
        // 批量通知:使用队列
        if ($recipient_count > 100) {
            return $this->strategies['batch'];
        }
        
        // 高优先级:立即发送
        if ($priority === 'high') {
            return $this->strategies['priority'];
        }
        
        // 默认:根据系统负载决定
        $system_load = $this->get_system_load();
        
        if ($system_load > 80) {
            // 高负载时使用队列
            return $this->strategies['batch'];
        } else {
            // 低负载时立即发送
            return $this->strategies['immediate'];
        }
    }
    
    private function get_system_load() {
        if (function_exists('sys_getloadavg')) {
            $load = sys_getloadavg();
            return $load[0] * 100; // 转换为百分比
        }
        
        // 备用方案:检查数据库连接数
        global $wpdb;
        $connections = $wpdb->get_var("SHOW STATUS LIKE 'Threads_connected'");
        return min(100, ($connections / 100) * 100);
    }
}

/**
 * 立即投递策略
 */
class Immediate_Delivery_Strategy {
    public function deliver($message_data) {
        // 直接写入数据库并尝试实时推送
        $message_system = new Advanced_Message_System();
        
        // 保存到数据库
        $result = $message_system->send_message(
            $message_data['sender_id'],
            $message_data['recipients'],
            $message_data['content'],
            $message_data['subject'] ?? ''
        );
        
        // 尝试实时推送
        $this->attempt_realtime_push($message_data, $result);
        
        return $result;
    }
}

5.2 性能优化与缓存策略

/**
 * 消息系统缓存优化
 */
class Message_Cache_Optimizer {
    
    private $cache_group = 'message_system';
    private $cache_expiration = 3600; // 1小时
    
    public function __construct() {
        // 初始化缓存
        if (!wp_cache_get('message_cache_initialized', $this->cache_group)) {
            $this->initialize_cache();
        }
        
        // 注册缓存清理钩子
        add_action('message_sent', array($this, 'invalidate_thread_cache'), 10, 3);
        add_action('notification_created', array($this, 'invalidate_notification_cache'), 10, 2);
    }
    
    public function get_user_threads_with_cache($user_id, $page = 1, $per_page = 20) {
        $cache_key = "user_{$user_id}_threads_page_{$page}";
        
        // 尝试从缓存获取
        $cached = wp_cache_get($cache_key, $this->cache_group);
        
        if ($cached !== false) {
            return $cached;
        }
        
        // 缓存未命中,查询数据库
        global $wpdb;
        
        $offset = ($page - 1) * $per_page;
        
        $threads = $wpdb->get_results($wpdb->prepare(
            "SELECT t.thread_id, t.subject, t.last_message_time,
                    (SELECT message_content FROM {$wpdb->prefix}messages 
                     WHERE thread_id = t.thread_id 
                     ORDER BY message_time DESC LIMIT 1) as last_message,
                    (SELECT COUNT(*) FROM {$wpdb->prefix}messages m2 
                     WHERE m2.thread_id = t.thread_id 
                     AND m2.is_read = 0 
                     AND m2.sender_id != %d) as unread_count
             FROM {$wpdb->prefix}message_threads t
             INNER JOIN {$wpdb->prefix}message_participants p ON t.thread_id = p.thread_id
             WHERE p.user_id = %d AND p.deleted = 0
             ORDER BY t.last_message_time DESC
             LIMIT %d OFFSET %d",
            $user_id, $user_id, $per_page, $offset
        ));
        
        // 存入缓存
        wp_cache_set($cache_key, $threads, $this->cache_group, $this->cache_expiration);
        
        return $threads;
    }
    
    public function get_user_unread_count_with_cache($user_id) {
        $cache_key = "user_{$user_id}_unread_count";
        
        $count = wp_cache_get($cache_key, $this->cache_group);
        
        if ($count === false) {
            global $wpdb;
            
            $count = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) 
                 FROM {$wpdb->prefix}messages m
                 INNER JOIN {$wpdb->prefix}message_participants p ON m.thread_id = p.thread_id
                 WHERE p.user_id = %d 
                 AND m.sender_id != %d
                 AND m.is_read = 0
                 AND p.deleted = 0",
                $user_id, $user_id
            ));
            
            wp_cache_set($cache_key, $count, $this->cache_group, 300); // 5分钟缓存
        }
        
        return intval($count);
    }
    
    public function invalidate_thread_cache($message_id, $thread_id, $sender_id) {
        // 获取线程参与者
        global $wpdb;
        
        $participants = $wpdb->get_col($wpdb->prepare(
            "SELECT user_id FROM {$wpdb->prefix}message_participants 
             WHERE thread_id = %d AND deleted = 0",
            $thread_id
        ));
        
        // 清除所有参与者的线程缓存
        foreach ($participants as $user_id) {
            wp_cache_delete("user_{$user_id}_unread_count", $this->cache_group);
            
            // 清除分页缓存(假设最多10页)
            for ($page = 1; $page <= 10; $page++) {
                wp_cache_delete("user_{$user_id}_threads_page_{$page}", $this->cache_group);
            }
        }
    }
}

5.3 安全与权限控制

/**
 * 消息系统安全层
 */
class Message_Security_Layer {
    
    public function __construct() {
        // 添加安全钩子
        add_filter('message_before_send', array($this, 'validate_message_content'));
        add_filter('message_recipient_list', array($this, 'filter_recipients'));
        add_action('message_after_send', array($this, 'log_message_activity'));
    }
    
    public function validate_message_content($message_data) {
        $content = $message_data['content'];
        
        // 1. 内容长度限制
        if (strlen($content) > 5000) {
            throw new Exception('消息内容过长,最多允许5000字符');
        }
        
        // 2. HTML过滤
        $allowed_tags = array(
            'a' => array('href' => array(), 'title' => array()),
            'br' => array(),
            'em' => array(),
            'strong' => array(),
            'p' => array(),
            'ul' => array(),
            'ol' => array(),
            'li' => array()
        );
        
        $message_data['content'] = wp_kses($content, $allowed_tags);
        
        // 3. 敏感词过滤
        $message_data['content'] = $this->filter_sensitive_words($message_data['content']);
        
        // 4. 链接安全检查
        $message_data['content'] = $this->validate_links($message_data['content']);
        
        return $message_data;
    }
    
    public function filter_recipients($recipients, $sender_id) {
        $filtered_recipients = array();
        
        foreach ($recipients as $recipient_id) {
            // 1. 不能给自己发消息(除非是系统消息)
            if ($recipient_id == $sender_id && $sender_id != 0) {
                continue;
            }
            
            // 2. 检查用户是否存在且未禁用
            $user = get_user_by('id', $recipient_id);
            if (!$user || $this->is_user_blocked($user->ID)) {
                continue;
            }
            
            // 3. 检查发送者是否被接收者屏蔽
            if ($this->is_blocked_by_user($sender_id, $recipient_id)) {
                continue;
            }
            
            // 4. 检查每日发送限制
            if (!$this->check_daily_message_limit($sender_id, $recipient_id)) {
                continue;
            }
            
            $filtered_recipients[] = $recipient_id;
        }
        
        return array_unique($filtered_recipients);
    }
    
    private function check_daily_message_limit($sender_id, $recipient_id) {
        global $wpdb;
        
        $today_start = date('Y-m-d 00:00:00');
        
        $count = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) 
             FROM {$wpdb->prefix}messages m
             INNER JOIN {$wpdb->prefix}message_participants p ON m.thread_id = p.thread_id
             WHERE m.sender_id = %d 
             AND p.user_id = %d
             AND m.message_time >= %s",
            $sender_id, $recipient_id, $today_start
        ));
        
        // 每天最多发送10条消息给同一用户
        return $count < 10;
    }
    
    public function log_message_activity($message_id, $thread_id, $sender_id) {
        global $wpdb;
        
        $wpdb->insert(
            $wpdb->prefix . 'message_audit_log',
            array(
                'message_id' => $message_id,
                'thread_id' => $thread_id,
                'user_id' => $sender_id,
                'action' => 'send_message',
                'ip_address' => $this->get_client_ip(),
                'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
                'timestamp' => current_time('mysql')
            ),
            array('%d', '%d', '%d', '%s', '%s', '%s', '%s')
        );
    }
}

总结与选择建议

6.1 各方案对比分析

方案 适用场景 优点 缺点 推荐指数
方案一:原生功能 小型网站、个人博客 简单易实现、无需额外依赖 性能差、功能有限 ★★☆☆☆
方案二:自定义表 中小型社区、企业站 性能好、功能完整 实现复杂、维护成本高 ★★★☆☆
方案三:WebSocket 实时聊天、在线客服 实时性强、用户体验好 服务器要求高、实现复杂 ★★★★☆
方案四:微服务 大型平台、分布式系统 高扩展性、易于维护 架构复杂、部署困难 ★★★☆☆
方案五:混合方案 中大型商业项目 灵活智能、性能优化 实现最复杂、需要经验 ★★★★★

6.2 实施建议

  1. 对于初学者:建议
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/296.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部