Workerman本身不提供GPS轨迹追踪能力,仅负责高效长连接通信;真实轨迹数据需由客户端每1–3秒通过WebSocket或HTTP POST上报经纬度等字段,服务端用WebSocketServer接收并校验,存入Redis缓存最新位置,再异步落库至MySQL或TimescaleDB存储完整历史轨迹。

Workerman 本身不提供 GPS 轨迹追踪能力,它只负责高效、稳定的长连接通信;真实轨迹数据必须由客户端(App)持续上报经纬度,服务端用 Workerman 接收、广播、存储并做轻量处理。
如何用 Workerman 接收司机/乘客的实时位置上报
客户端(如 Android/iOS App)需每 1–3 秒通过 WebSocket 或 HTTP POST 向 Workerman 服务发送 latitude、longitude、timestamp、user_id 和 role(driver/passenger)等字段。
Workerman 服务端建议用 WebsocketServer 接收,避免 HTTP 频繁建连开销:
use Workerman\Worker;
use Workerman\WebSocket\Connection;
$ws_worker = new Worker('websocket://0.0.0.0:2346');
$ws_worker->onMessage = function($connection, $data) {
$msg = json_decode($data, true);
if (!$msg || !isset($msg['user_id'], $msg['latitude'], $msg['longitude'])) {
$connection->close();
return;
}
// 存入内存或 Redis(见下节)
$key = 'location:' . $msg['user_id'];
$redis->setex($key, 60, json_encode([
'lat' => $msg['latitude'],
'lng' => $msg['longitude'],
'ts' => time(),
'role' => $msg['role']
]));
};
- 务必校验
user_id合法性(如 JWT 解析或 session 绑定),防止伪造位置 - 不要在
onMessage中执行耗时操作(如写 MySQL 主库),优先走 Redis + 异步队列落盘 - 单连接频繁发包(如 max_package_size 或心跳超时
怎么让乘客端实时看到司机移动轨迹(WebSocket 广播)
关键不是“推全量轨迹”,而是“推增量位置点 + 做连接绑定”。乘客进入订单页后,前端建立 WebSocket 连接,并传参 order_id 或 driver_id;服务端据此将该连接加入对应 driver 的广播组。
推荐用 Workerman 内置的 connections + 自定义分组管理(不用 register 扩展,除非集群部署):
// 上报位置时,查出当前订单的乘客连接并广播
$driver_id = $msg['user_id'];
$order = $db->fetch('SELECT passenger_id FROM orders WHERE driver_id = ? AND status = ?', [$driver_id, 'running']);
if ($order && isset($all_connections[$order['passenger_id']])) {
foreach ($all_connections[$order['passenger_id']] as $conn) {
$conn->send(json_encode([
'type' => 'driver_location',
'lat' => $msg['latitude'],
'lng' => $msg['longitude'],
'ts' => $msg['timestamp']
]));
}
}
- 避免全量广播(
$worker->connections遍历所有连接),必须按业务维度(如 order_id)索引连接 - 移动端弱网下可能断连,需前端实现重连 + 断线期间的位置补偿逻辑(服务端可缓存最近 5 个点)
- 轨迹平滑靠客户端插值(如贝塞尔曲线),服务端只管准确、低延迟送达点坐标
Redis 存位置 vs MySQL 存轨迹,该怎么选
Redis 适合存「当前最新位置」和「最近 30 秒轨迹缓存」,MySQL(或 TimescaleDB)才适合存「完整历史轨迹」用于后续分析、判责、计费。
-
SET location:uid123 "{...}" EX 60:供实时查询用,TTL 设为略大于上报周期(如 60s) -
LPUSH track:uid123 "{...}"+LTRIM track:uid123 0 199:缓存最近 200 个点,供断线重连时补帧 - 真正落库走异步:上报位置后,投递到
php-resque或amqp队列,由 worker 进程批量写入trips_tracks表,含point(PostGIS)、speed、accuracy - 别用 Redis 持久化轨迹——RDB/AOF 不保证写入顺序,且大 key(几万点)会阻塞主线程
真正的难点不在 Workerman 怎么写,而在于客户端定位精度控制(GPS/基站/WiFi 混合)、服务端连接生命周期管理(断网重连、多端登录踢出)、以及轨迹点去噪(如过滤瞬移、静止误报)。这些都得结合具体机型、网络环境和业务规则来调,Workerman 只是那根稳稳托住数据流的管道。

















