Verbindungen eines Members beenden
Die Channel-Autorisierung steuert Subscriptions, weist aber keine Identität auf Verbindungsebene zu. Ohne diese Identität schließt eine Abmeldung an anderer Stelle weder einen bestehenden Socket noch entfernt sie dessen Channel-Subscriptions.
Rufen Sie signin() auf, um der Verbindung eine member_id aus Ihrem Backend zuzuweisen. Die Disconnect-Operation kann dann alle Verbindungen schließen, die dieser Member in der App hält.
Verwenden Sie diesen Ablauf nach einer Remote-Abmeldung, einem Token-Widerruf, einer Sperre, einer Passwortänderung oder dem Entfernen eines Workspace-Platzes.
1. Die Verbindung anmelden
Richten Sie den Client auf einen Endpunkt in Ihrem eigenen Backend und rufen Sie signin() einmal auf:
import { BirdRealtime } from "@messagebird/realtime";
const bird = new BirdRealtime({
appKey: "your-app-key",
region: "us1",
memberAuthEndpoint: "/bird/auth/member",
});
const member = await bird.signin();
console.log("signed in as", member.member_id);import BirdRealtime
let bird = BirdRealtime(options: .init(
appKey: "your-app-key",
region: "us1",
memberAuthEndpoint: URL(string: "https://your-backend.example.com/bird/auth/member")
))
let member = try await bird.signin()
print("signed in as", member.memberId)import com.bird.realtime.BirdRealtime
import com.bird.realtime.BirdRealtimeOptions
val bird = BirdRealtime(
BirdRealtimeOptions(
appKey = "your-app-key",
region = "us1",
memberAuthEndpoint = "https://your-backend.example.com/bird/auth/member",
)
)
val member = bird.signin() // suspending
println("signed in as ${member.memberId}")Die Identität gehört zur Verbindung. Rufen Sie signin() einmal auf, und der Client meldet sich nach jedem Reconnect erneut an.
Die Anmeldung autorisiert keine Channel-Subscriptions. Private und Presence Channels rufen weiterhin Ihren Channel-Autorisierungsendpunkt auf. Eine Verbindung ohne Member-Identität kann jeden Channel abonnieren, den dieser Endpunkt genehmigt. Siehe Channels autorisieren.
2. Die Identität von Ihrem Backend signieren
Der Client sendet die Connection-ID in einem POST-Request:
Codebeispiel
{ "connection_id": "26896.319537" }Ihr Endpunkt antwortet mit der Identität als JSON-String sowie einer Signatur über genau diesen String:
Codebeispiel
{
"auth": "your-app-key:8f9a…",
"member_data": "{\"member_id\":\"u_42\",\"member_info\":{\"name\":\"Ada\"}}"
}Der zu signierende String ist <connection_id>::member::<member_data>, mit zwei Doppelpunkten auf jeder Seite von member. Hashen Sie ihn mit HMAC-SHA256 und dem App-Secret, hex-codieren Sie das Ergebnis und stellen Sie den App-Key voran:
import { createHmac } from "node:crypto";
app.post("/bird/auth/member", (req, res) => {
const { connection_id } = req.body;
// Your own decision: who is this caller, and may they connect at all?
const user = getUserFromSession(req);
if (!user) return res.sendStatus(403);
const memberData = JSON.stringify({
member_id: user.id,
member_info: { name: user.name },
});
const sig = createHmac("sha256", process.env.BIRD_REALTIME_SECRET)
.update(`${connection_id}::member::${memberData}`)
.digest("hex");
res.json({ auth: `${process.env.BIRD_REALTIME_KEY}:${sig}`, member_data: memberData });
});import hmac, hashlib, json, os
def sign_in(connection_id: str, user) -> dict:
key = os.environ["BIRD_REALTIME_KEY"]
secret = os.environ["BIRD_REALTIME_SECRET"].encode()
member_data = json.dumps({"member_id": user.id, "member_info": {"name": user.name}})
to_sign = f"{connection_id}::member::{member_data}"
sig = hmac.new(secret, to_sign.encode(), hashlib.sha256).hexdigest()
return {"auth": f"{key}:{sig}", "member_data": member_data}func signIn(connectionID string, user User) (map[string]string, error) {
key := os.Getenv("BIRD_REALTIME_KEY")
secret := []byte(os.Getenv("BIRD_REALTIME_SECRET"))
memberData, err := json.Marshal(map[string]any{
"member_id": user.ID,
"member_info": map[string]string{"name": user.Name},
})
if err != nil {
return nil, err
}
mac := hmac.New(sha256.New, secret)
mac.Write([]byte(connectionID + "::member::" + string(memberData)))
return map[string]string{
"auth": key + ":" + hex.EncodeToString(mac.Sum(nil)),
"member_data": string(memberData),
}, nil
}function signIn(string $connectionId, User $user): array
{
$key = getenv('BIRD_REALTIME_KEY');
$secret = getenv('BIRD_REALTIME_SECRET');
$memberData = json_encode(['member_id' => $user->id, 'member_info' => ['name' => $user->name]]);
$sig = hash_hmac('sha256', "{$connectionId}::member::{$memberData}", $secret);
return ['auth' => "{$key}:{$sig}", 'member_data' => $memberData];
}Signieren Sie exakt den member_data-String, den Sie zurückgeben. Erneutes Serialisieren des Objekts kann die Bytes verändern und die Signatur ungültig machen.
member_id ist der Wert, auf den die Disconnect-Operation zielt. Er akzeptiert bis zu 128 URL-sichere Zeichen, einschließlich + : @ . _ -, aber nicht / ? # % oder Whitespace. Falls Ihr Bezeichner nicht unterstützte Zeichen enthält, bilden Sie ihn vor dem Signieren auf einen stabilen sicheren Wert ab. Die Edge lehnt eine ungültige Member-ID ab und lässt die Verbindung ohne eine Identität, auf die die Disconnect-Operation zielen kann.
member_info ist optional. Bei der Verbindungsanmeldung wird der Wert an diesen Client zurückgegeben, nicht an einen Presence Channel gesendet.
Die Identität kann auch ein watchlist-Array mit Member-IDs enthalten. In Apps mit aktiviertem watchlist_events wird die Verbindung dann informiert, wenn diese Member online oder offline gehen; siehe Watchlist-Events.
Der hier signierte String ist bewusst nicht der String, den eine Presence-Subscription signiert. So kann eine Presence-Autorisierung niemals wiedergegeben werden, um eine Identität zu beanspruchen, obwohl beide Payloads member_data heißen.
3. Den Member trennen
await bird.realtime.members.disconnect("rap_01krdgeqcxet5s7t44vh8rt9mg", "u_42");client.realtime.members.disconnect("rap_01krdgeqcxet5s7t44vh8rt9mg", "u_42")if err := client.Realtime.Members.Disconnect(context.Background(), "rap_01krdgeqcxet5s7t44vh8rt9mg", "u_42"); err != nil {
log.Fatal(err)
}$bird->realtime->members->disconnect('rap_01krdgeqcxet5s7t44vh8rt9mg', 'u_42');curl -X POST \
https://us1.platform.bird.com/v1/realtime/apps/rap_01krdgeqcxet5s7t44vh8rt9mg/members/u_42/disconnect \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET"Die Operation schließt alle angemeldeten Verbindungen dieses Members in der App, einschließlich anderer Tabs und Geräte. Anonyme Verbindungen oder Verbindungen eines anderen Members werden nicht geschlossen.
Was der Client sieht
Die Verbindung wird mit Code 4009 geschlossen und stellt keine automatische Neuverbindung her:
bird.connection.bind("error", (e) => {
if (e.code === 4009) showSignedOutScreen();
});bird.onError { error in
if error.code == 4009 { showSignedOutScreen() }
}bird.onError { error ->
if (error.code == 4009) showSignedOutScreen()
}Zeigen Sie einen abgemeldeten Zustand an, wenn die Authentifizierung beendet ist. Der Aufruf von bird.connect() startet eine neue Verbindung, die sich über Ihren Endpunkt anmeldet. Stellen Sie die Verbindung daher erst wieder her, nachdem sich der Autorisierungsstatus des Members geändert hat.
Ein Anmeldefehler schließt den Socket nicht. Der Client meldet den Fehler separat und lässt die Verbindung ohne Member-Identität. Nach einem Reconnect meldet der Client dies über signin_error, weil das ursprüngliche signin()-Promise bereits aufgelöst wurde.
bird.connection.bind("signin_error", (e) => {
console.warn("connection has no identity:", e.message);
});bird.onSigninError { error in
print("connection has no identity:", error.message)
}bird.onSigninError { error ->
println("connection has no identity: ${error.message}")
}Die Verbindung kann weiterhin Events von autorisierten Channels empfangen, aber Member-Event- und Disconnect-Operationen können sie nicht ansprechen. Im Browser-Client ist bird.signedInMember in diesem Zustand null.
Erneutes Verbinden verhindern
Die Disconnect-Operation schließt aktuelle Verbindungen, ohne eine dauerhafte Sperre zu erzeugen. Derselbe Client kann sich erneut verbinden.
Widerrufen Sie die Sitzung oder vermerken Sie die Sperre, bevor Sie den Member trennen. Ihr Member-Autorisierungsendpunkt kann dann 403 Forbidden zurückgeben, falls der Client sich erneut verbindet.
Nächste Schritte
- Channels autorisieren behandelt die andere Signatur, die Ihr Backend berechnet, für Private- und Presence-Subscriptions.
- Einen Member trennen ist die vollständige API-Referenz für den Request.
- Events an einen Member senden ist die andere member-adressierte Operation.
- Presence Channels erklären, warum ein Member mehrere Verbindungen halten kann.
Related resources
Continue with the documentation, guides and examples for this topic. Resources are in English.
Explore the capabilityRealtimeFollow the learning pathBuild your first integrationImplementation guideSend your first realtime event
Try the practice and get an implementation brief