AKStream.Next · 文档中心

Let business users join safely

Let business users join safely

Your backend knows its users and meeting membership. It checks the business user first, then uses an AKStream.Next API token stored on the server to create a room or issue a one-use join ticket. Browsers and apps receive only their own ticket, never an administrator password or long-lived API token.

flowchart LR
    U["User signs in to your product"] --> B["Your backend checks meeting eligibility"]
    B --> A["AKStream.Next issues accessTicket"]
    A --> C["Approved device calls RTC SDK join"]
    C --> T["SDK holds and renews device RTC token"]

Three backend steps

  1. Use your business rules to decide who may join and whether they may host, publish, or only watch.
  2. Create or choose a room with your server-side API token. mediaServerId must refer to a registered media node.
  3. Issue a ticket for that user through POST /api/v2/rtc/rooms/{roomId}/access-tickets. Give roomId and accessTicket to the approved device for this join.

Example request. Take subjectId from a verified backend user session, never a role or identity submitted by the client:

POST /api/v2/rtc/rooms/{roomId}/access-tickets
Authorization: Bearer <API token stored on your backend>
Content-Type: application/json

{"subjectIssuer":"business-app","subjectId":"user-1001","displayName":"Alex","role":"viewer","capabilities":["publications.subscribe"],"expiresInMinutes":5,"bypassWaitingRoom":false}

This is a receive-only member. If a user may speak or publish video, your backend selects an appropriate role and requests microphone.publish or camera.publish. The server still intersects these requests with room policy. Admission tickets expire and are consumed once. If joining fails, first determine whether the ticket was already consumed before issuing another.

For a Node.js backend using standard fetch, put the following function behind an authenticated business route. The server derives user.id and canSpeak; it must not trust a role submitted by the browser. Set AKSTREAM_URL and AKSTREAM_API_TOKEN on the backend before calling it:

export async function issueRtcTicket(roomId, user, canSpeak) {
  const base = process.env.AKSTREAM_URL
  const token = process.env.AKSTREAM_API_TOKEN
  if (!base || !token || !roomId || !user?.id) throw new Error('Missing service configuration or verified user')
  const response = await fetch(new URL(`/api/v2/rtc/rooms/${encodeURIComponent(roomId)}/access-tickets`, base), {
    method: 'POST',
    headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      subjectIssuer: 'business-app',
      subjectId: String(user.id),
      displayName: String(user.displayName || user.id),
      role: canSpeak ? 'speaker' : 'viewer',
      capabilities: canSpeak
        ? ['microphone.publish', 'camera.publish', 'publications.subscribe', 'chat.send']
        : ['publications.subscribe'],
      expiresInMinutes: 5,
      bypassWaitingRoom: false
    }),
    signal: AbortSignal.timeout(15000)
  })
  if (!response.ok) throw new Error(`AKStream.Next ticket request failed: HTTP ${response.status}`)
  const ticket = await response.json()
  return { roomId, accessTicket: ticket.accessTicket, expiresAtUtc: ticket.expiresAtUtc }
}

Issue a receive-only ticket first, verify that the returned room ID matches and the ticket is present, then join on the client. For 401 inspect the backend API token, for 403 inspect rtc.manage and room eligibility, and for 429 respect the rate limit. Log the status and business request ID, never the complete accessTicket.

On the client

Call the target SDK's join or joinWithAccessTicket. The SDK manages the RTC token, signaling, media, and renewal. A Waiting result means wait for host admission and do not publish yet. participantId identifies a member in one meeting; deviceSessionId identifies a device session. Do not merge multiple devices merely because their display names match.

Clients need an HTTPS address and reachable media ports. Its certificate must match the domain or IP the device actually uses. A page loading successfully does not prove the ICE media route works. See Ports, domains, and HTTPS.

Render actual SDK state after joining; do not persist or decode the RTC token. Call SDK leave when the user departs. Closing a browser tab or Activity alone does not guarantee immediate cleanup. Choose your client target next.