微软跨平台maui开发chatgpt客户端

2023-06-09 15:24:02
image 什么是maui .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动(ios,andriod)和桌面(windows,mac)应用。 image chagpt 最近这玩意很火,由于网页版本限制了ip,还得必须开代理, 用起来比较
image
image

什么是maui

.NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动(ios,andriod)和桌面(windows,mac)应用。

image
image

chagpt

最近这玩意很火,由于网页版本限制了ip,还得必须开代理, 用起来比较麻烦,所以我尝试用maui开发一个聊天小应用 结合 chatgpt的开放api来实现(很多客户端使用网页版本接口用cookie的方式,有很多限制(如下图)总归不是很正规)

image
image

效果如下

image
image

mac端由于需要升级macos13才能开发调试,这部分我还没有完成,不过maui的控件是跨平台的,放在后续我升级系统再说

本项目开源

https://github.com/yuzd/maui_chatgpt

学习maui的老铁支持给个star

开发实战

我是设想开发一个类似jetbrains的ToolBox应用一样,启动程序在桌面右下角出现托盘图标,点击图标弹出应用(风格在windows mac平台保持一致)

需要实现的功能一览

  • 托盘图标(右键点击有menu)
  • webview(js和csharp互相调用)
  • 聊天SPA页面(react开发,build后让webview展示)

新建一个maui工程(vs2022)

image
image

坑一: 默认编译出来的exe是直接双击打不开的

image
image

工程文件加上这个配置

<WindowsPackageType>None</WindowsPackageType><WindowsAppSDKSelfContainedCondition="'$(IsUnpackaged)'=='true'">true</WindowsAppSDKSelfContained><SelfContainedCondition="'$(IsUnpackaged)'=='true'">true</SelfContained>

以上修改后,编译出来的exe双击就可以打开了

托盘图标(右键点击有menu)

启动时设置窗口不能改变大小,隐藏titlebar, 让Webview控件占满整个窗口

image
image

这里要根据平台不同实现不同了,windows平台采用winAPI调用,具体看工程代码吧

WebView

在MainPage.xaml 添加控件

image
image

对应的静态html等文件放在工程的 Resource\Raw文件夹下 (整个文件夹里面默认是作为内嵌资源打包的,工程文件里面的如下配置起的作用)

<!--RawAssets(alsoremovethe"Resources\Raw"prefix)--><MauiAssetInclude="Resources\Raw\**"LogicalName="%(RecursiveDir)%(Filename)%(Extension)"/>
image
image

【重点】js和csharp互相调用

这部分我找了很多资料,最终参考了这个demo,然后改进了下

https://github.com/mahop-net/Maui.HybridWebView

主要原理是:

  • js调用csharp方法前先把数据存储在localstorage里
  • 然后windows.location切换特定的url发起调用,返回一个promise,等待csharp的事件
  • csharp端监听webview的Navigating事件,异步进行下面处理
  • 根据url解析出来localstorage的key
  • 然后csharp端调用excutescript根据key拿到localstorage的value
  • 进行逻辑处理后返回通过事件分发到js端

js的调用封装如下:

//调用csharp的方法封装exportdefaultclassCsharpMethod{constructor(command,data){this.RequestPrefix="request_csharp_";this.ResponsePrefix="response_csharp_";//唯一this.dataId=this.RequestPrefix+newDate().getTime();//调用csharp的命令this.command=command;//参数this.data={command:command,data:!data?'':JSON.stringify(data),key:this.dataId}}//调用csharp返回promisecall(){//把data存储到localstorage中目的是让csharp端获取参数localStorage.setItem(this.dataId,this.utf8_to_b64(JSON.stringify(this.data)));leteventKey=this.dataId.replace(this.RequestPrefix,this.ResponsePrefix);letthat=this;constpromise=newPromise(function(resolve,reject){consteventHandler=function(e){window.removeEventListener(eventKey,eventHandler);letresp=e.newValue;if(resp){//从base64转换letrealData=that.b64_to_utf8(resp);if(realData.startsWith('err:')){reject(realData.substr(4));}else{resolve(realData);}}else{reject("unknownerror:"+eventKey);}};//注册监听回调(csharp端处理完发起的)window.addEventListener(eventKey,eventHandler);});//改变location发送给csharp端window.location="/api/"+this.dataId;returnpromise;}//转成base64解决中文乱码utf8_to_b64(str){returnwindow.btoa(unescape(encodeURIComponent(str)));}//从base64转过来解决中文乱码b64_to_utf8(str){returndecodeURIComponent(escape(window.atob(str)));}}

前端的使用方式

importCsharpMethodfrom'../../services/api'//发起调用csharp的chat事件函数constmethod=newCsharpMethod("chat",{msg:message});method.call()//call返回promise.then(data=>{//拿到csharp端的返回后展示onMessageHandler({message:data,username:'Robot',type:'chat_message'});}).catch(err=>{alert(err);});

csharp端的处理:

image
image

这么封装后,js和csharp的互相调用就很方便了

chatgpt的开放api调用

注册号chatgpt后可以申请一个APIKEY

image
image

API封装:

publicstaticasyncTask<CompletionsResponse>GetResponseDataAsync(stringprompt){//SetuptheAPIURLandAPIkeystringapiUrl="https://api.openai.com/v1/completions";//GettherequestbodyJSONdecimaltemperature=decimal.Parse(Setting.Temperature,CultureInfo.InvariantCulture);intmaxTokens=int.Parse(Setting.MaxTokens,CultureInfo.InvariantCulture);stringrequestBodyJson=GetRequestBodyJson(prompt,temperature,maxTokens);//SendtheAPIrequestandgettheresponsedatareturnawaitSendApiRequestAsync(apiUrl,Setting.ApiKey,requestBodyJson);}privatestaticstringGetRequestBodyJson(stringprompt,decimaltemperature,intmaxTokens){//SetuptherequestbodyvarrequestBody=newCompletionsRequestBody{Model="text-davinci-003",Prompt=prompt,Temperature=temperature,MaxTokens=maxTokens,TopP=1.0m,FrequencyPenalty=0.0m,PresencePenalty=0.0m,N=1,Stop="[END]",};//CreateanewJsonSerializerOptionsobjectwiththeIgnoreNullValuesandIgnoreReadOnlyPropertiespropertiessettotruevarserializerOptions=newJsonSerializerOptions{IgnoreNullValues=true,IgnoreReadOnlyProperties=true,};//SerializetherequestbodytoJSONusingtheJsonSerializer.SerializemethodoverloadthattakesaJsonSerializerOptionsparameterreturnJsonSerializer.Serialize(requestBody,serializerOptions);}privatestaticasyncTask<CompletionsResponse>SendApiRequestAsync(stringapiUrl,stringapiKey,stringrequestBodyJson){//CreateanewHttpClientformakingtheAPIrequestusingHttpClientclient=newHttpClient();//SettheAPIkeyintherequestheadersclient.DefaultRequestHeaders.Add("Authorization","Bearer"+apiKey);//CreateanewStringContentobjectwiththeJSONpayloadandthecorrectcontenttypeStringContentcontent=newStringContent(requestBodyJson,Encoding.UTF8,"application/json");//SendtheAPIrequestandgettheresponseHttpResponseMessageresponse=awaitclient.PostAsync(apiUrl,content);//DeserializetheresponsevarresponseBody=awaitresponse.Content.ReadAsStringAsync();//ReturntheresponsedatareturnJsonSerializer.Deserialize<CompletionsResponse>(responseBody);}

调用方式

varreply=awaitChatService.GetResponseDataAsync('xxxxxxxxxx');

完整代码参考 https://github.com/yuzd/maui_chatgpt

在学习maui的过程中,遇到问题我在microsoft learn提问,回答的效率很快,推荐大家试试看

image
image

关于我

image
image

微软最有价值专家是微软公司授予第三方技术专业人士的一个全球奖项。27年来,世界各地的技术社区领导者,因其在线上和线下的技术社区中分享专业知识和经验而获得此奖项。

MVP是经过严格挑选的专家团队,他们代表着技术最精湛且最具智慧的人,是对社区投入极大的热情并乐于助人的专家。MVP致力于通过演讲、论坛问答、创建网站、撰写博客、分享视频、开源项目、组织会议等方式来帮助他人,并最大程度地帮助微软技术社区用户使用Microsoft技术。

更多详情请登录官方网站https://mvp.microsoft.com/zh-cn

免责声明:文章内容不代表本站立场,本站不对其内容的真实性、完整性、准确性给予任何担保、暗示和承诺,仅供读者参考,文章版权归原作者所有。如本文内容影响到您的合法权益(内容、图片等),请及时联系本站,我们会及时删除处理。
本文链接:http://ai.ibashu.cn/news/show_414339.html

推荐资讯

CHATGPT问答模板
CHATGPT问答模板是一种用于撰写问答文章的标准化格式,它便于读者快速了解问题并得到相应的回答。此模板主要包含以下几个部分:1. 标题:标题应简短明了,符合文章主旨,能够吸引读者的
魔法闪电CHATGPT
魔法闪电CHATGPT是一款创新型的聊天机器人,它使用了深度学习技术来提供人类与机器之间的自然语言交流。它能够基于用户输入的信息,在实时模式下生成智能、有趣和幽默的回复。在这篇文
ChatGPT开发实战
1.概述 前段时间使用体验了ChatGPT的用法,感受到ChatGPT的强大,通过搜索关键字或者输入自己的意图,能够快速得到自己想要的信息和结果。今天笔者将深挖一下ChatGPT,给大家介绍如何使用ChatGPT的API来实战开发一些例子。 2.内容 2.1 ChatGPT起源 这个还得从谷歌发布B
ipset的学习与使用
ipset的学习与使用 场景说明 虽然可以通过: firewall-cmd --zone=trusted --add-source=$1 --permanent &amp;&amp; firewall-cmd --reload 或者是 firewall-cmd --zone=public --add
百度文心一言内测申请地址,文心一言API申请地址!
3月16日下午百度在北京召开了基于百度大语言模型的'文心一言'AI聊天机器人的发布会,对标ChatGPT! 首批用户将在3月16日通过邀请码可直接体验到!后续将开放更多人体验~ 文心一言内测预约地址:https://yiyan.b...
用Python实现ChatGPT智能机器人
最近,ChatGPT突然大火,说是十分的智能,可以写诗,写报告,甚至写论文,报着试试看的态度,我也研究了一下,找了很多资料,写了一个智能机器人的小demo。 因为ChatGPT依赖于OpenAI,所以,需要有OpenAI的Key,具体的申请步骤我也是参考了某个博主的博客,但是前提是你需要有个国外的手
CHATGPT拓展思考
在我们的日常生活中,很少有人会想到如何拓展自己的思维。然而,拓展思考能够帮助我们在各种不同的情境中更好地进行决策,更好地处理问题,更好地应对挑战。因此,本文将介绍使用“CHA
CHATGPT微信中文版
CHATGPT是一个基于GPT-3技术的交互式聊天机器人,它可以对人类语言的输入做出自然、流畅的回复。本文将介绍CHATGPT微信中文版的相关信息。CHATGPT微信中文版是一个新的交互式聊天机器人,它可
CHATGPT对话文本
CHATGPT(Conversational Mechanical Turk Generated Personalized Text)是一种生成式AI模型,可以根据用户输入的问题或话题进行自动回答和生成对话文本。CHATGPT的应用范围非常广泛,可以用于智能客服、虚拟

最新上架

最新资讯