React Native Twillio:错误:{“error”:“无效的访问令牌颁发者/主题”,“roomName”:“my_room”,“roomSid”:“”}

问题描述 投票:0回答:1

我正在用 React Native 构建视频通话应用程序。我成功生成了令牌,现在当我尝试设置视频通话时,它会抛出此错误:

ERROR:  {"error": "Invalid Access Token issuer/subject", "roomName": "my_room", "roomSid": ""}

我正在使用

"twilio": "^3.56.0"
但最新版本的
react-native-twilio-video-webrtc

这是我的App.js

import React, { Component } from "react";
import {
  StyleSheet,
  Text,
  TextInput,
  View,
  Button,
  TouchableOpacity,
  Platform,
} from "react-native";

import {
  TwilioVideoLocalView,
  TwilioVideoParticipantView,
  TwilioVideo,
} from "react-native-twilio-video-webrtc";

class App extends Component {
  state = {
    isAudioEnabled: true,
    isVideoEnabled: true,
    status: "disconnected",
    participants: new Map(),
    videoTracks: new Map(),
    roomName: "my_room",
    token:
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJZU0s3NGIyMGFmMWMwNGYyNzg2OTBhNDA4MDkyMGRjNTY2OC0xNjg0NTc3NDU3IiwiZ3JhbnRzIjp7ImlkZW50aXR5IjoidGVzdCIsInZpZGVvIjp7InJvb20iOiJteV9yb29tIn19LCJpYXQiOjE2ODQ1Nzc0NTcsImV4cCI6MTY4NDU4MTA1NywiaXNzIjoiWVNLNzRiMjBhZjFjMDRmMjc4NjkwYTQwODA5MjBkYzU2NjgiLCJzdWIiOiJBQzA4NTVmY2Q5MGVhNzc0NjA2NzI2NGY1ZTFiMzhlNjNjIn0.ONkDw-6X5MtaCVmSiZAFknIflt4zRA-6oP7zA1Nxt14",
  };

  _onConnectButtonPress = () => {
    try {
      this.twilioRef.connect({
        roomName: this.state.roomName,
        accessToken: this.state.token,
      });
    } catch (error) {
      console.log(error);
    }

    this.setState({ status: "connecting" });
  };

  _onEndButtonPress = () => {
    this.twilioRef.disconnect();
  };

  _onMuteButtonPress = () => {
    this.twilioRef
      .setLocalAudioEnabled(!this.state.isAudioEnabled)
      .then((isEnabled) => this.setState({ isAudioEnabled: isEnabled }));
  };

  _onFlipButtonPress = () => {
    this.twilioRef.flipCamera();
  };

  _onRoomDidConnect = () => {
    this.setState({ status: "connected" });
  };

  _onRoomDidDisconnect = ({ roomName, error }) => {
    console.log("ERROR: ", error);

    this.setState({ status: "disconnected" });
  };

  _onRoomDidFailToConnect = (error) => {
    console.log("ERROR: ", error);

    this.setState({ status: "disconnected" });
  };

  _onParticipantAddedVideoTrack = ({ participant, track }) => {
    console.log("onParticipantAddedVideoTrack: ", participant, track);

    this.setState({
      videoTracks: new Map([
        ...this.state.videoTracks,
        [
          track.trackSid,
          { participantSid: participant.sid, videoTrackSid: track.trackSid },
        ],
      ]),
    });
  };

  _onParticipantRemovedVideoTrack = ({ participant, track }) => {
    console.log("onParticipantRemovedVideoTrack: ", participant, track);

    const videoTracks = this.state.videoTracks;
    videoTracks.delete(track.trackSid);

    this.setState({ videoTracks: new Map([...videoTracks]) });
  };

  setTwilioRef = (ref) => {
    this.twilioRef = ref;
  };

  render() {
    return (
      <View style={styles.container}>
        {this.state.status === "disconnected" && (
          <View>
            <Text style={styles.welcome}>React Native Twilio Webrtc</Text>
            <TextInput
              style={styles.input}
              autoCapitalize="none"
              value={this.state.roomName}
              onChangeText={(text) => this.setState({ roomName: text })}
            ></TextInput>
            <TextInput
              style={styles.input}
              autoCapitalize="none"
              value={this.state.token}
              onChangeText={(text) => this.setState({ token: text })}
            ></TextInput>
            <Button
              title="Connect"
              style={styles.button}
              onPress={this._onConnectButtonPress}
            ></Button>
          </View>
        )}

        {this.state.status === "connected" ||
        this.state.status === "connecting" ? (
          <View style={styles.callContainer}>
            {this.state.status === "connected" && (
              <View style={styles.remoteGrid}>
                {Array.from(
                  this.state.videoTracks,
                  ([trackSid, trackIdentifier]) => {
                    return (
                      <TwilioVideoParticipantView
                        style={styles.remoteVideo}
                        key={trackSid}
                        trackIdentifier={trackIdentifier}
                      />
                    );
                  }
                )}
              </View>
            )}
            <View style={styles.optionsContainer}>
              <TouchableOpacity
                style={styles.optionButton}
                onPress={this._onEndButtonPress}
              >
                <Text style={{ fontSize: 12 }}>End</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.optionButton}
                onPress={this._onMuteButtonPress}
              >
                <Text style={{ fontSize: 12 }}>
                  {this.state.isAudioEnabled ? "Mute" : "Unmute"}
                </Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.optionButton}
                onPress={this._onFlipButtonPress}
              >
                <Text style={{ fontSize: 12 }}>Flip</Text>
              </TouchableOpacity>
              <TwilioVideoLocalView enabled={true} style={styles.localVideo} />
              <View />
            </View>
          </View>
        ) : null}

        <TwilioVideo
          ref={this.setTwilioRef}
          onRoomDidConnect={this._onRoomDidConnect}
          onRoomDidDisconnect={this._onRoomDidDisconnect}
          onRoomDidFailToConnect={this._onRoomDidFailToConnect}
          onParticipantAddedVideoTrack={this._onParticipantAddedVideoTrack}
          onParticipantRemovedVideoTrack={this._onParticipantRemovedVideoTrack}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "white",
  },
  callContainer: {
    flex: 1,
    position: "absolute",
    bottom: 0,
    top: 0,
    left: 0,
    right: 0,
  },
  welcome: {
    fontSize: 30,
    textAlign: "center",
    paddingTop: 40,
  },
  input: {
    height: 50,
    borderWidth: 1,
    marginRight: 70,
    marginLeft: 70,
    marginTop: 50,
    textAlign: "center",
    backgroundColor: "white",
  },
  button: {
    marginTop: 100,
  },
  localVideo: {
    flex: 1,
    width: 125,
    height: 200,
    position: "absolute",
    right: 10,
    bottom: 400,
    borderRadius: 2,
    borderColor: "#4e4e4e",
  },
  remoteGrid: {
    flex: 1,
    flexDirection: "row",
    flexWrap: "wrap",
  },
  remoteVideo: {
    width: "100%",
    height: "100%",
  },
  optionsContainer: {
    position: "absolute",
    left: 0,
    bottom: 0,
    right: 0,
    height: 100,
    // backgroundColor: "blue",
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
  },
  optionButton: {
    width: 60,
    height: 60,
    marginLeft: 10,
    marginRight: 10,
    borderRadius: 100 / 2,
    backgroundColor: "grey",
    justifyContent: "center",
    alignItems: "center",
  },
});

export default App;


Here is how i generate token

const twilio = require("twilio");

const token = async () => {
  const accountSid = "";
  const apiKeySid = "";
  const apiKeySecret = "";

  // Generate an access token
  const AccessToken = twilio.jwt.AccessToken;
  const VideoGrant = AccessToken.VideoGrant;

  const token = new AccessToken(accountSid, apiKeySid, apiKeySecret);
  token.identity = "test"; // Set the user identity

  // Grant access to a specific room
  const videoGrant = new VideoGrant({ room: "my_room" });
  token.addGrant(videoGrant);

  // Set token expiration (optional)
  token.ttl = 3600; // 1 hour

  // Return the token as a response
  console.log(token.toJwt());
};

token();
react-native twilio twilio-api twilio-programmable-chat twilio-click-to-call
1个回答
0
投票

你曾经让它工作过吗?我也有同样的问题

© www.soinside.com 2019 - 2024. All rights reserved.