Neeche ek minimum working example hai jisme:
React user apni location send karta hai.
FastAPI JWT se user identify karta hai.
Backend friend list check karta hai.
Sirf friends ko location update milta hai.
Frontend map ki jagah simple console update dikhata hai (map baad me add kar sakte ho).
Backend (FastAPI)
Dummy Friend Data
FRIENDS = {
1: [2, 3],
2: [1],
3: [1]
}
User 1 ki location sirf 2 aur 3 dekh sakte hain.
main.py
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
import jwt
import json
app = FastAPI()
SECRET_KEY = "mysecret"
active_connections = {}
FRIENDS = {
1: [2, 3],
2: [1],
3: [1]
}
def get_user_from_token(token: str):
try:
payload = jwt.decode(
token,
SECRET_KEY,
algorithms=["HS256"]
)
return payload["user_id"]
except Exception:
return None
@app.websocket("/ws/location")
async def location_socket(websocket: WebSocket):
token = websocket.query_params.get("token")
user_id = get_user_from_token(token)
if not user_id:
await websocket.close(code=1008)
return
await websocket.accept()
active_connections[user_id] = websocket
print(f"User {user_id} connected")
try:
while True:
data = await websocket.receive_text()
payload = json.loads(data)
location_update = {
"type": "location_update",
"user_id": user_id,
"lat": payload["lat"],
"lng": payload["lng"]
}
friend_ids = FRIENDS.get(user_id, [])
for friend_id in friend_ids:
friend_socket = active_connections.get(friend_id)
if friend_socket:
await friend_socket.send_json(
location_update
)
except WebSocketDisconnect:
active_connections.pop(user_id, None)
print(f"User {user_id} disconnected")
JWT Generate Example
import jwt
token = jwt.encode(
{"user_id": 1},
"mysecret",
algorithm="HS256"
)
print(token)
React Sender (Location Owner)
User 1 ki location continuously bhejega.
import { useEffect } from "react";
export default function ShareLocation() {
useEffect(() => {
const token =
"USER_1_JWT_TOKEN";
const ws = new WebSocket(
`ws://localhost:8000/ws/location?token=${token}`
);
let watchId;
ws.onopen = () => {
watchId =
navigator.geolocation.watchPosition(
(position) => {
ws.send(
JSON.stringify({
lat:
position.coords.latitude,
lng:
position.coords.longitude
})
);
},
console.error,
{
enableHighAccuracy: true
}
);
};
return () => {
navigator.geolocation.clearWatch(
watchId
);
ws.close();
};
}, []);
return (
<h2>
Sharing Location...
</h2>
);
}
React Friend Side
User 2 ya User 3.
Ye sirf updates receive karega.
import { useEffect, useState } from "react";
export default function FriendTracker() {
const [locations, setLocations] =
useState({});
useEffect(() => {
const token =
"USER_2_JWT_TOKEN";
const ws = new WebSocket(
`ws://localhost:8000/ws/location?token=${token}`
);
ws.onmessage = (event) => {
const data =
JSON.parse(event.data);
setLocations((prev) => ({
...prev,
[data.user_id]: {
lat: data.lat,
lng: data.lng
}
}));
};
return () => ws.close();
}, []);
return (
<div>
<h2>
Friend Locations
</h2>
{Object.entries(locations).map(
([userId, loc]) => (
<div key={userId}>
User {userId}
<br />
Lat: {loc.lat}
<br />
Lng: {loc.lng}
</div>
)
)}
</div>
);
}
Real Production Version
Dummy dictionary ki jagah:
friend_ids = await db.fetch_all("""
SELECT friend_id
FROM friendships
WHERE user_id = :user_id
AND status = 'accepted'
""")
Better Structure
users
------
id
friendships
------
user_id
friend_id
status
location_shares
------
owner_id
viewer_id
expires_at
locations
------
user_id
latitude
longitude
updated_at
Location send karne se pehle:
allowed_users = get_location_viewers(
user_id
)
Fir:
for viewer in allowed_users:
send_location()
Is model me tum WhatsApp jaisa feature bana sakte ho:
Friend request
Accept request
Live location sharing
Share for 15 min
Share for 1 hour
Stop sharing
Last seen location
Multiple friends tracking
aur backend hi enforce karega ki location sirf authorized friends ko mile.
Bilkul. Real apps me location hamesha share nahi hoti. User button dabata hai:
Start Sharing → location bhejna start
Stop Sharing → location bhejna band
Iske liye frontend me watchPosition() ka watchId save karte hain aur backend ko bhi batate hain ki sharing on/off hai.
React
import { useRef, useState } from "react";
export default function LiveLocation() {
const [sharing, setSharing] = useState(false);
const wsRef = useRef(null);
const watchIdRef = useRef(null);
const startSharing = () => {
const token = localStorage.getItem("token");
const ws = new WebSocket(
`ws://localhost:8000/ws/share-location?token=${token}`
);
wsRef.current = ws;
ws.onopen = () => {
watchIdRef.current =
navigator.geolocation.watchPosition(
(position) => {
ws.send(
JSON.stringify({
type: "location",
lat: position.coords.latitude,
lng: position.coords.longitude,
})
);
},
console.error,
{
enableHighAccuracy: true,
}
);
setSharing(true);
};
};
const stopSharing = () => {
if (watchIdRef.current) {
navigator.geolocation.clearWatch(
watchIdRef.current
);
}
if (
wsRef.current &&
wsRef.current.readyState === WebSocket.OPEN
) {
wsRef.current.send(
JSON.stringify({
type: "stop_sharing",
})
);
wsRef.current.close();
}
setSharing(false);
};
return (
<div>
{!sharing ? (
<button onClick={startSharing}>
Start Live Location
</button>
) : (
<button onClick={stopSharing}>
Stop Live Location
</button>
)}
</div>
);
}
FastAPI
Connection management:
from fastapi import FastAPI, WebSocket
import json
app = FastAPI()
active_connections = {}
WebSocket Endpoint
@app.websocket("/ws/share-location")
async def share_location(
websocket: WebSocket
):
token = websocket.query_params.get(
"token"
)
user_id = verify_jwt(token)
await websocket.accept()
active_connections[user_id] = websocket
try:
while True:
raw = await websocket.receive_text()
data = json.loads(raw)
if data["type"] == "stop_sharing":
print(
f"{user_id} stopped sharing"
)
break
if data["type"] == "location":
lat = data["lat"]
lng = data["lng"]
friends = get_friends(user_id)
for friend_id in friends:
friend_socket = (
active_connections.get(
friend_id
)
)
if friend_socket:
await friend_socket.send_json(
{
"type":
"friend_location",
"user_id":
user_id,
"lat":
lat,
"lng":
lng,
}
)
finally:
active_connections.pop(
user_id,
None
)
await websocket.close()
Better Approach (Recommended)
Database me store karo ki sharing active hai ya nahi.
Table:
CREATE TABLE location_sharing (
user_id UUID PRIMARY KEY,
is_active BOOLEAN,
started_at TIMESTAMP
);
Start button:
UPDATE location_sharing
SET is_active = true
WHERE user_id = ?
Stop button:
UPDATE location_sharing
SET is_active = false
WHERE user_id = ?
Broadcast se pehle:
if not is_sharing_enabled(user_id):
continue
WhatsApp Style
Agar WhatsApp jaisa banana hai:
User click:
Share Live Location
Options:
15 minutes
1 hour
8 hours
DB:
user_id
expires_at
Check:
if datetime.utcnow() > expires_at:
stop_sharing()
To location automatically band ho jayegi.
Typical Production Flow
User A
|
| Start Sharing Button
v
watchPosition()
|
WebSocket
|
FastAPI
|
Check friends
|
Send updates
|
Friend B
Friend C
User A
|
| Stop Sharing Button
v
clearWatch()
|
WebSocket close
|
Backend removes connection
|
Location sharing stopped
Is tarah user ke paas poora control rahega: ek button se start, dusre click se stop, aur sirf authorized friends ko hi location updates milengi.