You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移动端与Web端实时通知实现方案咨询(PHP+MySQL+Retrofit)

实现PHP+MySQL环境下的移动端与Web面板实时通知方案

1. 选择PHP WebSocket库:Ratchet

Ratchet是PHP生态中成熟的WebSocket实现,能无缝对接现有PHP后端,适合你的场景。

安装Ratchet

通过Composer安装依赖:

composer require cboden/ratchet

编写基础WebSocket服务器

创建websocket-server.php,实现连接管理和消息转发逻辑:

<?php
require __DIR__ . '/vendor/autoload.php';

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

class ReportNotificationServer implements MessageComponentInterface {
    protected $adminConnections;

    public function __construct() {
        $this->adminConnections = new \SplObjectStorage;
    }

    // 验证管理员身份并保存连接
    public function onOpen(ConnectionInterface $conn) {
        parse_str($conn->httpRequest->getUri()->getQuery(), $params);
        if (isset($params['admin_token']) && $this->validateAdminToken($params['admin_token'])) {
            $this->adminConnections->attach($conn);
            echo "管理员已连接: {$conn->resourceId}\n";
        } else {
            $conn->close();
        }
    }

    // 转发新报告通知给所有在线管理员
    public function onMessage(ConnectionInterface $from, $msg) {
        $data = json_decode($msg, true);
        if ($data['type'] === 'new_report') {
            foreach ($this->adminConnections as $conn) {
                $conn->send(json_encode([
                    'type' => 'new_report',
                    'report_id' => $data['report_id'],
                    'title' => $data['title'],
                    'timestamp' => date('Y-m-d H:i:s')
                ]));
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        $this->adminConnections->detach($conn);
        echo "管理员已断开连接: {$conn->resourceId}\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "错误: {$e->getMessage()}\n";
        $conn->close();
    }

    // 自定义管理员token验证逻辑(从MySQL查询)
    private function validateAdminToken($token) {
        $pdo = new PDO('mysql:host=localhost;dbname=your_db', 'db_user', 'db_pass');
        $stmt = $pdo->prepare('SELECT id FROM admins WHERE token = ? AND is_active = 1');
        $stmt->execute([$token]);
        return $stmt->rowCount() > 0;
    }
}

// 启动服务器,监听8080端口
$server = IoServer::factory(
    new HttpServer(new WsServer(new ReportNotificationServer())),
    8080
);

echo "WebSocket服务器已启动,监听端口8080\n";
$server->run();

2. 在PHP API中触发通知

当用户通过Retrofit提交报告到API接口时,向WebSocket服务器发送通知:

// 提交报告的API接口示例
public function submitReport(Request $request) {
    // 1. 保存报告到MySQL
    $report = Report::create([
        'user_id' => $request->user_id,
        'title' => $request->title,
        'content' => $request->content
    ]);

    // 2. 向WebSocket服务器发送通知
    $socket = fsockopen('localhost', 8080, $errno, $errstr, 30);
    if ($socket) {
        $msg = json_encode([
            'type' => 'new_report',
            'report_id' => $report->id,
            'title' => $report->title
        ]);
        // 构造WebSocket文本帧发送
        $frame = "\x81" . chr(strlen($msg)) . $msg;
        fwrite($socket, $frame);
        fclose($socket);
    }

    return response()->json(['status' => 'success', 'report_id' => $report->id]);
}

生产环境建议用Ratchet的Client组件或Redis做消息中转,提升可靠性

3. Web面板实现WebSocket客户端

在管理员面板前端添加WebSocket连接与消息监听:

const adminToken = '当前管理员的有效token'; // 从后端获取
const ws = new WebSocket(`ws://your-domain.com:8080?admin_token=${adminToken}`);

ws.onopen = () => console.log('已连接到通知服务器');

ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.type === 'new_report') {
        // 显示通知并更新报告列表
        alert(`新报告:${data.title}(ID: ${data.report_id})`);
        updateReportList(data.report_id);
    }
};

ws.onclose = () => {
    console.log('连接断开,3秒后重连');
    setTimeout(() => window.location.reload(), 3000);
};

ws.onerror = (error) => console.error('WebSocket错误:', error);

4. 移动端实现WebSocket客户端

Retrofit是HTTP库,WebSocket需基于OkHttp实现(Retrofit依赖OkHttp):

添加OkHttp依赖

在build.gradle中添加:

implementation 'com.squareup.okhttp3:okhttp:4.12.0'

编写WebSocket连接代码

import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import org.json.JSONObject

class NotificationWebSocketListener : WebSocketListener() {
    override fun onOpen(webSocket: WebSocket, response: okhttp3.Response) {
        super.onOpen(webSocket, response)
        // 连接成功后的初始化操作
    }

    override fun onMessage(webSocket: WebSocket, text: String) {
        super.onMessage(webSocket, text)
        val data = JSONObject(text)
        if (data.getString("type") == "report_approved") {
            // 处理管理员审批通知,调用系统通知
            showSystemNotification("报告已审批", data.getString("report_title"))
        }
    }

    override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
        super.onClosed(webSocket, code, reason)
        reconnect()
    }

    override fun onFailure(webSocket: WebSocket, t: Throwable, response: okhttp3.Response?) {
        super.onFailure(webSocket, t, response)
        reconnect()
    }

    private fun reconnect() {
        Thread.sleep(3000)
        startWebSocket()
    }

    private fun showSystemNotification(title: String, content: String) {
        // 实现Android/iOS系统通知逻辑
    }
}

fun startWebSocket() {
    val client = OkHttpClient()
    val request = Request.Builder()
        .url("ws://your-domain.com:8080?user_token=当前用户的token") // 验证用户身份
        .build()
    val listener = NotificationWebSocketListener()
    client.newWebSocket(request, listener)
}

5. 可靠性优化建议

  • 重连机制:客户端断开后自动重试连接,避免通知丢失
  • 离线消息存储:管理员离线时,将通知保存到MySQL,上线后同步未读通知
  • 身份验证:WebSocket连接必须验证身份,防止非法接入
  • 负载均衡:用户量较大时,用Redis做消息中转,配合多WebSocket服务器实例

内容的提问来源于stack exchange,提问作者Samreen Aziz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:02:02