成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

使用 .NET MAUI 開發 ChatGPT 客戶端的流程

瀏覽:214日期:2022-06-09 08:58:56
目錄
  • 開發實戰
    • 托盤圖標(右鍵點擊有 menu)
    • WebView
    • 【重點】js 和 csharp 互相調用
    • chatgpt 的開放 api 調用

最近 chatgpt 很火,由于網頁版本限制了 ip,還得必須開代理,用起來比較麻煩,所以我嘗試用 maui 開發一個聊天小應用,結合 chatgpt 的開放 api 來實現(很多客戶端使用網頁版本接口用 cookie 的方式,有很多限制(如下圖)總歸不是很正規)。

效果如下

mac 端由于需要升級 macos13 才能開發調試,這部分我還沒有完成,不過 maui 的控件是跨平臺的,放在后續我升級系統再說。

開發實戰

我是設想開發一個類似 jetbrains 的 ToolBox 應用一樣,啟動程序在桌面右下角出現托盤圖標,點擊圖標彈出應用(風格在 windows mac 平臺保持一致)

需要實現的功能一覽

  • 托盤圖標(右鍵點擊有 menu)
  • webview(js 和 csharp 互相調用)
  • 聊天 SPA 頁面(react 開發,build 后讓 webview 展示)

新建一個 maui 工程(vs2022)

坑一:默認編譯出來的 exe 是直接雙擊打不開的

工程文件加上這個配置

<WindowsPackageType>None</WindowsPackageType><WindowsAppSDKSelfContained Condition=""$(IsUnpackaged)" == "true"">true</WindowsAppSDKSelfContained><SelfContained Condition=""$(IsUnpackaged)" == "true"">true</SelfContained>

以上修改后,編譯出來的 exe 雙擊就可以打開了

托盤圖標(右鍵點擊有 menu)

啟動時設置窗口不能改變大小,隱藏 titlebar, 讓 Webview 控件占滿整個窗口

這里要根據平臺不同實現不同了,windows 平臺采用 winAPI 調用,具體看工程代碼吧!

WebView

在 MainPage.xaml 添加控件

對應的靜態 html 等文件放在工程的 Resource\Raw 文件夾下 (整個文件夾里面默認是作為內嵌資源打包的,工程文件里面的如下配置起的作用)

<!-- Raw Assets (also remove the "Resources\Raw" prefix) --><MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />

【重點】js 和 csharp 互相調用

這部分我找了很多資料,最終參考了這個 demo,然后改進了下。

主要原理是:

  • js 調用 csharp 方法前先把數據存儲在 localstorage 里
  • 然后 windows.location 切換特定的 url 發起調用,返回一個 promise,等待 csharp 的事件
  • csharp 端監聽 webview 的 Navigating 事件,異步進行下面處理
  • 根據 url 解析出來 localstorage 的 key
  • 然后 csharp 端調用 excutescript 根據 key 拿到 localstorage 的 value
  • 進行邏輯處理后返回通過事件分發到 js 端

js 的調用封裝如下:

// 調用csharp的方法封裝export default class CsharpMethod {  constructor(command, data) {    this.RequestPrefix = "request_csharp_";    this.ResponsePrefix = "response_csharp_";    // 唯一    this.dataId = this.RequestPrefix + new Date().getTime();    // 調用csharp的命令    this.command = command;    // 參數    this.data = { command: command, data: !data ? "" : JSON.stringify(data), key: this.dataId }  }   // 調用csharp 返回promise  call() {    // 把data存儲到localstorage中 目的是讓csharp端獲取參數    localStorage.setItem(this.dataId, this.utf8_to_b64(JSON.stringify(this.data)));    let eventKey = this.dataId.replace(this.RequestPrefix, this.ResponsePrefix);    let that = this;    const promise = new Promise(function (resolve, reject) {      const eventHandler = function (e) {window.removeEventListener(eventKey, eventHandler);let resp = e.newValue;if (resp) {  // 從base64轉換  let realData = that.b64_to_utf8(resp);  if (realData.startsWith("err:")) {    reject(realData.substr(4));  } else {    resolve(realData);  }} else {  reject("unknown error :" + eventKey);}      };      // 注冊監聽回調(csharp端處理完發起的)      window.addEventListener(eventKey, eventHandler);    });    // 改變location 發送給csharp端    window.location = "/api/" + this.dataId;    return promise;  }   // 轉成base64 解決中文亂碼  utf8_to_b64(str) {    return window.btoa(unescape(encodeURIComponent(str)));  }  // 從base64轉過來 解決中文亂碼  b64_to_utf8(str) {    return decodeURIComponent(escape(window.atob(str)));  } }

前端的使用方式

import CsharpMethod from "../../services/api" // 發起調用csharp的chat事件函數const method = new CsharpMethod("chat", {msg: message});method.call() // call返回promise.then(data =>{  // 拿到csharp端的返回后展示  onMessageHandler({    message: data,    username: "Robot",    type: "chat_message"  });}).catch(err =>  {    alert(err);});

csharp 端的處理:

這么封裝后,js 和 csharp 的互相調用就很方便了。

chatgpt 的開放 api 調用

注冊好 chatgpt 后可以申請一個 APIKEY。

API 封裝:

  public static async Task<CompletionsResponse> GetResponseDataAsync(string prompt){    // Set up the API URL and API key    string apiUrl = "https://api.openai.com/v1/completions";     // Get the request body JSON    decimal temperature = decimal.Parse(Setting.Temperature, CultureInfo.InvariantCulture);    int maxTokens = int.Parse(Setting.MaxTokens, CultureInfo.InvariantCulture);    string requestBodyJson = GetRequestBodyJson(prompt, temperature, maxTokens);     // Send the API request and get the response data    return await SendApiRequestAsync(apiUrl, Setting.ApiKey, requestBodyJson);} private static string GetRequestBodyJson(string prompt, decimal temperature, int maxTokens){    // Set up the request body    var requestBody = new CompletionsRequestBody    {Model = "text-davinci-003",Prompt = prompt,Temperature = temperature,MaxTokens = maxTokens,TopP = 1.0m,FrequencyPenalty = 0.0m,PresencePenalty = 0.0m,N = 1,Stop = "[END]",    };     // Create a new JsonSerializerOptions object with the IgnoreNullValues and IgnoreReadOnlyProperties properties set to true    var serializerOptions = new JsonSerializerOptions    {IgnoreNullValues = true,IgnoreReadOnlyProperties = true,    };     // Serialize the request body to JSON using the JsonSerializer.Serialize method overload that takes a JsonSerializerOptions parameter    return JsonSerializer.Serialize(requestBody, serializerOptions);} private static async Task<CompletionsResponse> SendApiRequestAsync(string apiUrl, string apiKey, string requestBodyJson){    // Create a new HttpClient for making the API request    using HttpClient client = new HttpClient();     // Set the API key in the request headers    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + apiKey);     // Create a new StringContent object with the JSON payload and the correct content type    StringContent content = new StringContent(requestBodyJson, Encoding.UTF8, "application/json");     // Send the API request and get the response    HttpResponseMessage response = await client.PostAsync(apiUrl, content);     // Deserialize the response    var responseBody = await response.Content.ReadAsStringAsync();     // Return the response data    return JsonSerializer.Deserialize<CompletionsResponse>(responseBody);}

調用方式

 var reply = await ChatService.GetResponseDataAsync("xxxxxxxxxx");

在學習 maui 的過程中,遇到問題我在 Microsoft Learn 提問,回答的效率很快,推薦大家試試看!

到此這篇關于使用 .NET MAUI 開發 ChatGPT 客戶端的文章就介紹到這了,更多相關.NET MAUI 開發 ChatGPT 內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

標簽: ASP.NET
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
日韩黄色小视频| 日韩欧美成人激情| 日韩免费观看高清完整版| 精品一区二区久久久| 色狠狠综合天天综合综合| 午夜精品久久久久久不卡8050| 亚洲激情婷婷| 国产精品国产a| 亚洲午夜在线| 亚洲丝袜另类动漫二区| 伊人久久久大香线蕉综合直播 | 中文字幕欧美激情一区| 91丨国产丨九色丨pron| 国产午夜精品一区二区三区视频| 成人aa视频在线观看| 欧美大片顶级少妇| 99精品视频中文字幕| 国产免费成人在线视频| 日韩精品一区二区三区视频在线观看| 欧美日韩免费观看一区| 国产成人福利片| 九九精品一区二区| 男女男精品视频| 亚洲精品国产第一综合99久久| 久久免费偷拍视频| ww久久中文字幕| 精品国产乱码久久久久久1区2区| 欧美一级免费观看| 欧美日韩国产高清一区| 欧美一a一片一级一片| 在线观看亚洲精品| 欧美三电影在线| 欧美日韩不卡在线| 欧美一级在线视频| 日韩一区二区高清| 日韩三级中文字幕| 精品精品国产高清a毛片牛牛| 欧美一区二区三区在线视频| 欧美一区二区三区四区在线观看 | 欧美日韩亚洲丝袜制服| 欧美性大战久久久久久久蜜臀| 欧美亚洲综合网| 欧美综合一区二区三区| 欧美伊人久久大香线蕉综合69| 国产亚洲网站| 亚洲精品国产无天堂网2021 | 欧美蜜桃一区二区三区| gogogo免费视频观看亚洲一| 中文字幕在线免费不卡| 香蕉视频成人在线观看| 免费高清视频精品| 色天使久久综合网天天| 欧美在线free| 欧美一区午夜精品| 精品国产123| 日本一区二区视频在线| 国产精品久久一卡二卡| 亚洲国产视频a| 精品系列免费在线观看| 成人听书哪个软件好| 欧美精品一线| 亚洲欧美日韩视频二区| 欧美亚洲综合一区| 久久亚区不卡日本| 亚洲精品精品亚洲| 天堂影院一区二区| 国产精品88av| 国产主播一区二区三区四区| 一本久道综合久久精品| 日本大香伊一区二区三区| 欧美一二三四在线| 国产精品日日摸夜夜摸av| 亚洲大片一区二区三区| 国内精品国产成人| jlzzjlzz亚洲女人18| 韩国亚洲精品| 午夜一区二区三视频在线观看| 91久久精品日日躁夜夜躁欧美| 欧美一区二区国产| 椎名由奈av一区二区三区| 午夜精品久久久久久久久| 国产乱子轮精品视频| 91浏览器在线视频| 亚洲欧美精品| 9191成人精品久久| 国产精品久久久久7777按摩| 午夜精品福利在线| 福利视频网站一区二区三区| 黄色国产精品| 在线精品亚洲一区二区不卡| 久久亚洲综合av| 亚洲国产美国国产综合一区二区| 国产盗摄一区二区三区| 亚洲国产精品久久久久久女王| 欧美男女性生活在线直播观看| 国产欧美日韩在线观看| 五月激情丁香一区二区三区| av午夜精品一区二区三区| 亚洲一区日韩| 久久综合五月天婷婷伊人| 一区二区三区影院| 精品一区二区三区在线播放视频| 亚洲精品一线二线三线无人区| 久久久夜夜夜| 亚洲一级网站| 成人动漫视频在线| 日本网站在线观看一区二区三区| 国产日韩欧美高清在线| 久久亚洲一区二区三区明星换脸| 国产精品动漫网站| 久草中文综合在线| 亚洲高清在线播放| 日韩限制级电影在线观看| 亚洲一区二区高清| 91丨porny丨首页| 91成人在线观看喷潮| 中文字幕中文在线不卡住| 国产激情一区二区三区四区 | 亚洲香蕉伊在人在线观| 99在线热播精品免费| 在线观看国产日韩| 亚洲欧美国产高清| 成人激情午夜影院| 色狠狠一区二区三区香蕉| 国产精品免费视频网站| 国产福利精品导航| 一本色道久久综合亚洲精品不| 女同性一区二区三区人了人一 | 亚洲人妖在线| 久久看人人爽人人| 自拍视频在线观看一区二区| 国产成人在线观看免费网站| 老司机午夜精品视频在线观看| 国产精品国产三级国产aⅴ无密码| 黄色小说综合网站| 一本色道久久综合亚洲aⅴ蜜桃 | 国产精品毛片a∨一区二区三区| 青青青爽久久午夜综合久久午夜| 亚洲国产第一| 国产精品三级电影| 风间由美一区二区三区在线观看 | 久久综合久久综合这里只有精品| 国产精品麻豆一区二区| 成人高清在线视频| 欧美精品欧美精品系列| 日韩精品亚洲专区| 99视频+国产日韩欧美| 国产三级三级三级精品8ⅰ区| 国产一区在线观看麻豆| 色婷婷综合五月| 午夜视频一区二区| 国产精品欧美日韩一区| 亚洲欧美日韩综合aⅴ视频| 欧美精品观看| 中文字幕免费在线观看视频一区| 欧美一区2区三区4区公司二百| 日韩三级视频在线看| 国产精选一区二区三区| 欧美日韩精品欧美日韩精品一综合| 日本不卡视频一二三区| 一本到三区不卡视频| 亚洲国产欧美一区二区三区丁香婷| 极品少妇一区二区三区| 中文字幕在线不卡国产视频| 欧美日韩精品一区| 国产精品的网站| 精品二区久久| 亚洲三级免费观看| 亚洲深夜av| 亚洲一卡二卡三卡四卡| 国产伦理一区| 亚洲一级二级在线| 久久福利毛片| 麻豆国产精品一区二区三区 | 欧美va亚洲va| av成人免费在线观看| 久久久五月婷婷| 91看片淫黄大片一级| 久久久高清一区二区三区| 欧美精品aa| 专区另类欧美日韩| 亚洲中午字幕| 蜜桃久久av一区| 欧美精品在欧美一区二区少妇| 国产精品一区免费在线观看| 日韩女优毛片在线| 欧美aa国产视频| 亚洲猫色日本管| 色伊人久久综合中文字幕| 国产一区二区看久久| 久久久蜜臀国产一区二区| 在线免费观看一区二区三区| 亚洲一区二区四区蜜桃| 日本道免费精品一区二区三区| 国产一区二区按摩在线观看| 精品国产1区2区3区| 精品不卡一区二区三区| 亚洲国产精品久久人人爱| 欧美性受xxxx黑人xyx| 成人一道本在线|