I am receiving this error when attempting to create a livestream channel on my website: Agora-SDK [ERROR]: [client-f42b7] join number: 1, Joining channel failed, rollback AgoraRTCException: AgoraRTCError CAN_NOT_GET_GATEWAY_SERVER: flag: 4096, message: AgoraRTCError CAN_NOT_GET_GATEWAY_SERVER: dynamic key expired. However as you can see in the code below I am generating a token and I even have a means of regenerating expired tokens.

`<?php

namespace App\Http\Controllers;

use App\Models\Channel;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
use App\Services\AgoraTokenService;
use App\Http\Controllers\TeammateController;
use App\Http\Controllers\ScoutController;

class ChannelController extends Controller
{
    protected $agoraTokenService;

    public function __construct(AgoraTokenService $agoraTokenService)
    {
        $this->agoraTokenService = $agoraTokenService;
    }

    public function generateAgoraToken(Request $request)
    {
        $channelName = $request->input('channelName');
        if (!$channelName) {
            return response()->json(['error' => 'Channel name is required.'], 400);
        }

        try {
            $token = $this->agoraTokenService->generateToken($channelName);
            return response()->json(['token' => $token]);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Failed to generate token: ' . $e->getMessage()], 500);
        }
    }

    public function index()
    {
        $userId = auth()->id();
        $teammateIds = TeammateController::getTeammateIds($userId);
        $scoutIds = ScoutController::getScoutIds($userId);
        $allIds = array_merge([$userId], $teammateIds, $scoutIds);
        $channels = Channel::whereIn('host_id', $allIds)->get();
        return view('channels.index', compact('channels'));
    }

    public function create()
    {
        return view('channels.create');
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'channelName' => 'nullable|string|max:255|unique:channels,channelName',
        ]);

        $channel = new Channel;
        $channel->host_id = auth()->id();
        $defaultChannelName = "LockerRoom Live with " . auth()->user()->username . "! " . Carbon::now()->format('m/d/Y g:i:s A');
        $originalChannelName = $data['channelName'] ?? $defaultChannelName;
        $sanitizedChannelName = preg_replace('/[^a-zA-Z0-9_]/', '_', $originalChannelName);
        $channel->channelName = $originalChannelName;
        $channel->sanitizedChannelName = $sanitizedChannelName;

        try {
            $token = $this->agoraTokenService->generateToken($channel->sanitizedChannelName);

            Log::info('Storing token for channel: ' . $channel->sanitizedChannelName);

            $channel->token = $token;
            $channel->token_expires_at = now()->addHours(24);
            $channel->save();

            return redirect()->route('channels.show', $channel->id)->with([
                'message' => 'Channel created successfully!',
                'token' => $token,
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to create channel: ' . $e->getMessage());
            return back()->with('error', 'Failed to create channel: ' . $e->getMessage());
        }
    }

    public function show(Channel $channel)
    {
        if ($channel->token_expires_at <= now()) {
            Log::warning('Token for channel ' . $channel->channelName . ' has expired. Regenerating.');
            $token = $this->agoraTokenService->generateToken($channel->sanitizedChannelName);
            $channel->token = $token;
            $channel->token_expires_at = now()->addHours(24);
            $channel->save();
        }

        else {
            $token = $channel->token;  // Get the token from the model if it's not expired
        }

        $isHost = auth()->id() === $channel->host_id;

        return view('channels.show', [
            'channel' => $channel,
            'token' => $token,
            'isHost' => $isHost,
            'agora_app_id' => config('agora.app_id')
        ]);
    }

    public function edit(Channel $channel)
    {
        return view('channels.edit', ['channel' => $channel]);
    }

    public function update(Request $request, Channel $channel)
    {
        $data = $request->validate([
            'channelName' => 'required|string|max:255|unique:channels,channelName,' . $channel->id,
        ]);

        $channel->channelName = $data['channelName'];

        // Update the sanitizedChannelName as well
        $channel->sanitizedChannelName = preg_replace('/[^a-zA-Z0-9_]/', '_', $channel->channelName);

        $channel->save();

        return redirect()->route('channels.show', $channel->id)->with('message', 'Channel updated successfully!');
    }

    public function destroy(Channel $channel)
    {
        if ($channel->host_id !== auth()->id()) {
            return redirect()->back()->with('error', 'Unauthorized action!');
        }

        $channel->delete();
        return redirect()->route('channels.index')->with('message', 'Channel deleted successfully!');
    }
}`


<?php

namespace App\Services;

use App\Services\Agora\AccessToken;
use App\Services\Agora\RtcTokenBuilder;
use Illuminate\Support\Facades\Log;

class AgoraTokenService
{
    private $appId;
    private $appCertificate;

    public function __construct()
    {
        $this->appId = config('agora.app_id');
        $this->appCertificate = config('agora.app_certificate');
    }

    public function generateToken($channelName)
    {
        try {
            $token = RtcTokenBuilder::buildTokenWithUid(
                $this->appId,
                $this->appCertificate,
                $channelName,
                0,
                RtcTokenBuilder::RolePublisher,
                86400
            );

            Log::info('Token generated for channel: ' . $channelName . ' Token: ' . $token);

            return $token;

        } catch (\Exception $e) {
            Log::error('Token generation failed: ' . $e->getMessage());
            throw new \Exception('Agora token generation failed: ' . $e->getMessage());
        }
    }
}

<div class="container">
    <h1>{{ $channel->channelName }}</h1>

    <div>
        <div id="agora-video-player"
            data-agora-app-id="{{ $agora_app_id }}"
            data-token="{{ $token }}"
            data-is-host="{{ $isHost }}"
            data-channel-name="{{ $channel->sanitizedChannelName }}"
            style="width: 100%; height: 400px; background-color: #eee;">
            Livestream Placeholder
        </div>
    </div>
</div>

<script src="{{ asset('build/assets/js/AgoraRTC_N-production.js') }}"></script>
<script src="{{ asset('build/assets/js/agoraSetup.js') }}"></script>

0

There are 0 best solutions below