亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何處理 DirectLine 連接錯誤

如何處理 DirectLine 連接錯誤

阿波羅的戰車 2023-03-03 15:19:51
我們使用 bot 框架運行一個 bot,并使用 JS 中的直線從我們的網站連接到它。我們從自定義 API 端點獲取令牌,并將令牌存儲在 sessionStorage 中。然后我們使用連接到機器人directLine = await window.WebChat.createDirectLine({  token,  conversationId,  watermark: "0"});一切正常,但是當我讓頁面打開的時間過長時,sessionStorage 中的令牌會過期。頁面刷新或導航到不同的頁面會導致方法內部出現 403 錯誤createDirectLine。只要 sessionStorage 持有該令牌,就會導致聊天機器人無法連接。這種行為對我來說并不奇怪,但我不知道如何處理。我想要的是簡單地清除 sessionStorge,請求一個新令牌并在發生這種情況時開始新對話。但我不知道該怎么做。如何從該方法中獲取 403 錯誤createDirectLine?或者有沒有辦法預先驗證令牌?我已經嘗試在該createDirectLine方法周圍放置一個 try/catch 塊,但是 403 錯誤沒有出現在 catch 中。
查看完整描述

2 回答

?
紅糖糍粑

TA貢獻1815條經驗 獲得超6個贊

此解決方案僅用于解決令牌過期后發生的 403 錯誤(我認為在 30 分鐘內)。更好的解決方案是將 conversationId 與令牌一起存儲并使用它獲取新令牌。檢查官方機器人服務文檔

// to shorten code, we store in sessionStorage as separate items.

const expirationDuration = 1000 * 60 * 30; // 30 minutes

const currentTime = new Date().getTime();

const timeTokenStored = sessionStorage.getItem("timeTokenStored") || currentTime;


// if token is stored over 30 minutes ago, ignore it and get a new one. Otherwise, use it.

if ((currentTime - timeTokenStored) > expirationDuration) {

      const res = await fetch('https://<yourTokenEndpoint>', { method: 'POST' });

      const { token } = await res.json();}

      const currentTime = new Date().getTime();

      sessionStorage.setItem("timeTokenStored", currentTime);

      sessionStorage.setItem('token', token);

else {

  const token = sessionStorage.getItem("token")

}

當您使用它時,您不妨將它存儲在 localStorage 中。這樣,您的機器人將跟隨用戶。


查看完整回答
反對 回復 2023-03-03
?
有只小跳蛙

TA貢獻1824條經驗 獲得超8個贊

我找到了解決方案。我們可以通過刷新令牌來檢查令牌是否有效。如果刷新導致錯誤,則令牌不再有效。如果刷新成功,令牌將再有效一個小時。


因此,我們向后端添加了(可重用的)函數以使用https://directline.botframework.com/v3/directline/tokens/refresh. 我們更改了前端代碼以調用我們新的刷新功能。


前端代碼:


// Gets a new token from the cloud.

async function requestToken() {

  if (!sessionStorage['webchatToken']) {

    const res = await fetch('https://' + serviceName + '.azurewebsites.net/api/token');

    // If the request was succesfull, store the token and userId.

    if (res.status == 200) {

      const jsonResult = await res.json();

      sessionStorage['webchatToken'] = jsonResult.token;

      sessionStorage['webchatUserId'] = jsonResult.userId;

      console.log(`Got token from cloud`);


      // refresh the token every 15 minutes.

      setTimeout(() => {

        refreshToken();

      }, 60000 * 15); // 15 minutes

    }

    // If the request was not succesfull, retry.

    else {

      console.log(`Tried to get token, but goterror ` + res.status + `. Retrying.`);

      await requestToken();

    }

  }

  // If there is already a token in storage, refresh the existing one instead of requesting a new one.

  else {

    console.log(`Got token from sessionStorage`);

    await refreshToken();

  }

}


// Refreshes an existing token so it doesn't expire.

async function refreshToken() {

  // Refresh the token if it exists in storage.

  if (sessionStorage['webchatToken']) {

    const res = await fetch('https://' + serviceName + '.azurewebsites.net/api/token/refresh?token=' + sessionStorage['webchatToken'],

    {

      method: 'POST'

    });

    // If refresh was succesfull we are done.

    if (res.status == 200) {

      console.log(`Refreshed token`);

    }

    // If refresh was not succesfull, clear the token from storage and request a new one. The token is probably expired.

    else {

      console.log(`Tried to refresh token, but got error ` + res.status + `. Requesting new token.`);

      sessionStorage.clear();

      await requestToken();

    }

  }

  // If there is no token in storage, request a new token.

  else {

    console.log(`Tried to refresh token, but token is not defined. Requesting new token.`);

    sessionStorage.clear();

    await requestToken();

  }

}

后端代碼:


[HttpGet]

[Route("api/token")]

public async Task<ObjectResult> GetToken()

{

  HttpClient client = new HttpClient();


  HttpRequestMessage request = new HttpRequestMessage(

    HttpMethod.Post,

    $"https://directline.botframework.com/v3/directline/tokens/generate");

 

  request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _configuration.DirectLineKey);


  var userId = $"dl_{Guid.NewGuid()}";


  request.Content = new StringContent(

    JsonConvert.SerializeObject(new { User = new { Id = userId } }),

    Encoding.UTF8,

    "application/json");


  var response = await client.SendAsync(request);

  string token = String.Empty;

  int expiresIn = 0;


  if (response.IsSuccessStatusCode)

  {

    var body = await response.Content.ReadAsStringAsync();

    token = JsonConvert.DeserializeObject<DirectLineToken>(body).token;

    expiresIn = JsonConvert.DeserializeObject<DirectLineToken>(body).expires_in;

  }


  return Ok(new { token, userId, expiresIn });

}


[HttpPost]

[Route("api/token/refresh/")]

public async Task<ObjectResult> RefreshToken(string token)

{

  HttpClient client = new HttpClient();


  HttpRequestMessage request = new HttpRequestMessage(

    HttpMethod.Post,

    $"https://directline.botframework.com/v3/directline/tokens/refresh");


  request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);



  var response = await client.SendAsync(request);

  token = String.Empty;

  int expiresIn = 0;


  if (response.IsSuccessStatusCode)

  {

    var body = await response.Content.ReadAsStringAsync();

    token = JsonConvert.DeserializeObject<DirectLineToken>(body).token;

    expiresIn = JsonConvert.DeserializeObject<DirectLineToken>(body).expires_in;

  }


  if (string.IsNullOrEmpty(token))

    return Problem("Token incorrect");


  return Ok(new { token, expiresIn });

}

我希望發布這個可能對某人有用。


查看完整回答
反對 回復 2023-03-03
  • 2 回答
  • 0 關注
  • 133 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號