Dvorak
Dvorak

Dvorak Chen

All Posts in 2024


GDB 调试 Rust 编译为 RISC-V 裸机代码

GDB调试Rust编译为RISC-V裸机代码的博客介绍了如何使用QEMU和GDB来调试编译为RISC-V裸机的二进制文件。在启动QEMU时,需要添加`-s`和`-S`参数,其中`-s`用于启用GDB服务器,默认在1234端口,`-S`用于在启动时暂停CPU。然后,可以使用gdb来进行调试。在进入gdb后,可以设置断点并执行代码,还可以使用`layout src`命令查看对应的Rust源码。如果在gdb中使用`layout src`无法显示源码,可能是因为没有执行下一步代码、使用了--release编译选项或链接器脚本去除了调试信息。博客提供了解决这些问题的建议,并提醒读者可以在网上找到更多有关gdb的命令。--GPT 4

Rust RISC-V

重新发明 Service Trait

重新发明Service Trait 这篇博客讲述了如何重新设计和改进Rust中的Service Trait。作者首先介绍了一个简单的HTTP服务器的实现,该服务器使用了三个Handler函数来处理请求。然后,作者展示了如何将这三个Handler函数组合成一个更通用的Handler。作者通过实现一个新的Handler trait,使用泛型和关联类型,使得Handler可以接受任意类型的请求和返回任意类型的响应。接下来,作者介绍了如何为Timeout和JsonContentType这两个Handler实现新的泛型版本。最后,作者讨论了Service trait的一个重要方法poll_ready,它可以用于拥塞控制。 这篇博客引发了一些有趣的问题,例如如何设计一个通用的Handler trait,以及如何实现拥塞控制。读者可以通过阅读全文来了解更多关于Rust中Service Trait的内容,并思考这些问题的答案。 摘要的最后提出了一个问题,即如何设计一个通用的Handler trait。这个问题可以激发读者的思考,并鼓励他们深入研究Rust中的Service Trait。--GPT 4

Rust

HTML 样式设计的兼容性考虑

HTML样式设计的兼容性考虑 这篇博客讨论了HTML元素的大小应该由其外部元素决定的概念。作者指出,这样设计的元素能够具有兼容性和伸缩性,适应不同大小的要求。通过使用Vue框架编写组件的例子,作者展示了组件和元素的伸缩性的重要性。他提到了一个手机组件的例子,该组件的固定宽高导致在不同屏幕上显示不完美。为了使组件具有伸缩性,作者建议将组件的宽高设置为100%,使其大小取决于使用它的地方。最后,作者指出并非所有组件都需要伸缩性,例如按钮组件可以使用固定的宽高。这篇博客引发了读者对HTML样式设计的思考,并提出了一个问题:什么样的元素需要具有伸缩性?--GPT 4

css

在 Dockerfile 里使用 crates 镜像提升 crates 下载速度

在这篇博客中,作者介绍了如何在Dockerfile中使用crates镜像来提高crates下载速度。文章首先说明了在国内访问crates时下载速度较慢的问题,并提出了在本地设置crates镜像的解决方案。然后,作者给出了在Dockerfile中添加镜像配置的具体步骤,并提到了与本地配置方式的细微差别。最后,作者引用了一个参考链接,供读者进一步了解和学习。通过本文,读者可以了解到如何在Dockerfile中使用crates镜像来提升下载速度,并且可以思考如何在其他环境中应用相似的镜像配置来优化软件开发过程中的依赖下载速度。--GPT 4

Rust

更好的 Javascript 运行时 Deno

# 更好的 Javascript 运行时 Deno 本博客介绍了一种更好的 JavaScript 运行时环境——Deno。与目前占据主导地位的Node不同,Deno提供了更好的使用体验。 Deno同样基于V8引擎,但与Node不同的是,Deno默认支持TypeScript,并提供了HTTP服务器等功能,而Node需要通过添加依赖来实现这些功能。 在安装Deno后,可以通过在控制台输入`deno -v`来查看Deno的版本。 Deno可以直接运行TypeScript,只需创建一个ts文件并编写代码,然后使用`deno`命令运行。此外,Deno还可以作为服务器使用,它提供了用于构建HTTP服务器的库。只需创建一个新文件并编写代码,然后使用`deno run --allow-net`命令运行即可。需要注意的是,在Deno中,默认情况下网络权限是关闭的,需要使用`--allow-net`参数开启。 通过使用Deno,无需安装任何依赖即可运行TypeScript和构建HTTP服务器。 想要了解更多关于Deno的信息,请查看[官方文档](https://deno.com/)。--GPT 4

Javascript

P2P 的使用 coturn 搭建 ICE 服务器

在这篇博客中,我们讨论了在NAT网络环境下进行P2P通信的问题,并介绍了使用STUN和TURN协议来解决这个问题。我们还介绍了如何使用coturn来搭建一个ICE服务器。首先,我们安装了coturn,并配置了证书和监听端口。然后,我们配置了用户名、密码和域名。最后,我们进行了测试,验证了STUN和TURN服务器的正常工作。我们还提供了让coturn在后台自启动的命令。通过阅读这篇博客,你将了解到如何搭建一个ICE服务器来支持P2P通信,并解决NAT网络环境下的问题。--GPT 4

network

Create your own simple reactivity front-end framework

创造你自己的简单响应式前端框架 本文介绍了如何创建一个简单的响应式前端框架。作者对Angular、Vue和React这三个主流前端框架进行了评价,并提到了自己对它们的喜好和不喜欢之处。作者决定尝试创建自己的响应式前端框架,类似于Solid并使用Signal。 首先,作者决定使用函数组件而不是类组件。作者展示了一个函数组件的例子,并介绍了如何通过编译器将jsx转换为普通的JavaScript代码。作者提到了SWC作为一个可用于转换JavaScript/TypeScript和支持jsx/tsx的工具,并提供了SWC playground用于查看jsx/tsx转换为JavaScript的过程。 接下来,作者讨论了响应式的实现。作者提到了Angular通过绑定变量、React通过虚拟DOM以及Solid使用Signal来实现响应式。作者决定使用Signal,并展示了如何使用createSignal创建一个信号,并在HTML中使用该信号的值。作者还展示了如何实现一个自定义的useSignal函数。 然后,作者讨论了如何在Dvorak.createElement函数中实现订阅值的逻辑。作者展示了如何在createElement函数中绑定属性值,并订阅相应的发布者。作者还展示了如何处理元素的子节点,并通过一个reactiveChildren函数实现了子节点的响应式。 总结起来,本文介绍了如何创建一个简单的基于Signal的响应式库。阅读全文可以了解更多细节和实现方法。 摘要:本文介绍了如何创建一个简单的响应式前端框架。作者讨论了Angular、Vue和React这三个前端框架,并决定尝试创建自己的框架。作者展示了如何使用SWC转换jsx/tsx为JavaScript,并介绍了Signal作为响应式的实现方式。作者还展示了如何实现一个简单的useSignal函数和reactiveChildren函数。阅读全文可以了解更多细节和实现方法。--GPT 4

Javascript

supplement of Authentication

# Authentication Failure Handling in .NET In my recent blog post titled ".NET Authentication and Authorization," I discussed the configuration and implementation of authentication and authorization in a .NET application. However, I failed to address an important aspect: handling authentication failures. By default, the authentication configuration in .NET uses a cookie policy. When an authentication failure occurs, it responds with a 302 status code and redirects to the `/Account/Login` page. This poses a problem when the frontend and backend of the application are separated, as the redirect will not point to the correct address. For instance, let's assume the frontend app is hosted at `localhost:8800` and the backend app at `localhost:9900`. If an authentication failure occurs during a frontend API request, the response will contain a 302 status code with the location set to `localhost:9900/Account/Login`. The frontend, using HTTP APIs like `fetch` or `Axios`, will automatically fol...--GPT 4

.NET

dotnet Authentication and Authorization

# .NET身份验证和授权 本篇博客介绍了在.NET中的身份验证和授权。使用了基于Cookie的身份验证,即用户身份信息将存储在Cookie中并响应给客户端。在控制器中,通过创建一个包含用户身份信息的`ClaimsPrincipal`对象,并使用`SignIn(claimsPrincipal, CookieAuthenticationDefaults.AuthenticationScheme)`方法将其发送给客户端: ```csharp var claims = new List<Claim> { new(ClaimTypes.Sid, <Id>,ClaimValueTypes.Sid, ISSUER, ISSUER), new(ClaimTypes.Email, <Email>, ClaimValueTypes.Email, ISSUER, ISSUER) }; var claimsIdentity = new ClaimsIdentity( claims, CookieAuthenticationDefaults.AuthenticationScheme); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); return SignIn(claimsPrincipal, CookieAuthenticationDefaults.AuthenticationScheme); ``` `SignIn`方法将创建一个包含Cookie的`SignInResult`对象,并将其从控制器返回给客户端,你可以在响应中看到`set-cookie`头部: ![file](/image/img-b9fca940-08db-4696-9537-d76aecf8a553.png) ## 我更喜欢使用Cookie 有多种身份验证方式可供选择,例如:Cookie、JWT等。如果我使用基于浏览器的客户端,我更倾向于使用Cookie,例如Web、Tauri、Electron等。 因为现代浏览器具有更高的安全性,它们会自动处理Cookie,接收Cookie并存储Cookie,并在发送请求时附加Cookie。客户端不需要额外处理Cookie。 相比之下,JWT会更加复杂。 包含用户身份信息的Cookie可...--GPT 4

.NET

play sound when piece moved

摘要: 这篇博客讲述了在国际象棋网站上添加一个新功能:当棋子移动时播放声音。作者最初认为这是一个很简单的功能,但最终发现并不像想象中那么简单。由于浏览器的自动播放策略,作者无法按照自己的意愿播放声音。 浏览器的自动播放策略规定: - 静音自动播放是允许的。 - 有声音的自动播放是允许的,如果: - 用户与该域进行了交互(点击、触摸等)。 - 在桌面上,用户的媒体参与指数已经超过了阈值,这意味着用户之前已经播放过带有声音的视频。 - 用户在移动设备上将该网站添加到了主屏幕或在桌面上安装了渐进式Web应用程序(PWA)。 - 顶级框架可以将自动播放权限委托给其内嵌框架,以允许带有声音的自动播放。 因此,在用户与页面进行交互之前,无法播放声音,在用户停止与页面进行交互时也无法播放声音。 为了解决这个问题,作者找到了一个绕过限制的方法:循环播放声音并调节音量!在棋子移动时将音量调节为1,棋子移动后将音量调节为0.0001。 为什么是0.0001而不是0或静音? 因为如果设置为静音或音量为0,将触发自动播放策略的限制,而将音量设置为1或取消静音将在用户停止与页面进行交互时被阻止。但是,如果将音量设置为足够低的值,就不会触发自动播放策略,因为声音仍在播放。 在代码中,作者使用了以下方法来实现: ```rust sound.volume = 1; setTimeout(() => { sound.currentTime = 0; sound.volume = 0.0001; }, 500); ``` 当音量为0.0001时,用户听不到声音。 需要注意的是,在移动设备上不允许将音量设置为1!因此,在移动设备上可以将音量设置为静音。 ```rust sound.muted = false; setTimeout(() => { sound.currentTime = 0; sound.muted = true; }, 500); ``` --GPT 4

Javascript

学学dotnet core中的身份验证和授权-2-cookie

学习dotnet core中的身份验证和授权-2-cookie 本文介绍了如何使用cookie进行基于声明的身份验证和授权。首先,通过登录接口获取凭证,然后将声明下发到客户端的cookie中。接着,使用身份验证中间件解析cookie中的声明。最后,通过定义基于声明的授权策略来对接口进行授权处理。文章还提到了如何使用AddAuthentication和AddCookie方法定义身份验证策略,并介绍了如何在接口上使用[Authorize("Need24")]来指定授权策略。最后,通过测试验证了身份验证和授权的生效。文章指出,虽然使用cookie进行身份验证和授权简单,但在实际情况中可能会遇到一些问题,如跨域情况。--GPT 4

.NET

学学dotnet core中的身份验证和授权-1-概念

学习.NET Core中的身份验证和授权-1-概念 本文旨在讲解.NET Core中的身份验证和授权的概念。身份验证和授权是相辅相成的,必须先进行身份验证才能进行授权。身份验证是为了证明来者的身份,而授权是根据身份的权限决定是否允许访问某个资源。在.NET Core中,身份验证和授权的信息传递通过声明(Claim)来实现。声明是身份的相关信息,每个声明由类型和值组成。通过身份验证后得到的声明将传递给授权程序,授权程序根据声明判断是否通过授权。授权通过将允许访问对应的资源,不通过将被拒绝。在下一篇文章中,我们将使用cookie来实现一个简单的身份验证和授权。通过本文的学习,你将了解身份验证和授权的关系以及如何使用声明进行授权判断。--GPT 4

.NET

Rust - bytecodec 编解码库

Rust - bytecodec Encoding and Decoding Library This blog post discusses the use of the bytecodec library in Rust for encoding and decoding data. The author starts by explaining the need for a simple protocol to serialize objects into binary format for network transmission. Instead of using JSON, the author decides to create a custom protocol where each field is represented on a separate line. However, the author soon realizes that the implementation becomes messy and lacks abstraction. The problem lies in the lack of a standardized approach to encoding and decoding. Although the `Peer` object only has three members, each member needs to be individually implemented for encoding and decoding. This lack of abstraction leads to inconsistent naming, implementation, and method usage, making the code difficult to manage. To solve this problem, the author proposes the use of traits to provide a standardized approach to encoding and decoding. The bytecodec library offers the `Encode` and `De...--GPT 4

Rust

Rust 小技巧之临时作用域

Rust小技巧之临时作用域 本文介绍了在Rust中使用临时作用域来优化代码的方法。首先,作者提到了在处理`Result`和`Option`时,可以使用`if let`和`?`操作符来简化代码。接下来,作者给出了一个读取用户输入的示例,并提出了优化的思路。首先,可以将读取输入的代码封装成一个函数,并返回所需的变量。其次,作者介绍了一种更喜欢的方法,即使用临时作用域来处理读取输入的操作。在临时作用域中定义的变量在作用域结束后会被释放,从而简化了代码。最后,作者比喻了临时作用域的好处,就像有一个只能放数据线的小盒子,能够方便地收纳数据线。通过使用临时作用域,可以提高代码的可读性和简洁性。 思考问题:你是否在自己的代码中使用过临时作用域?你认为在哪些情况下使用临时作用域会更加合适?--GPT 4

Rust

P2P 的 NAT

P2P的NAT 本文讨论了NAT(网络地址转换)的原理和对P2P通信的影响。NAT是为了解决IPv4地址不足的问题而出现的临时方案,但对互联网产生了负面影响。 首先,文章介绍了全局地址和专用地址的概念,以及NAT如何将专用地址映射为全局地址。 然后,文章讨论了NAT的缺点,包括违反IP地址设计原则、使网络变得脆弱、破坏网络分层结构模型等。 接下来,文章介绍了不同类型的NAT,包括全锥型、受限锥型、端口受限锥型和对称型,并解释了它们在P2P通信中的表现。 最后,文章讨论了在不同类型的NAT下如何实现P2P通信,并指出了一些无法建立P2P连接的情况。 总的来说,NAT是一个有用但失败的协议,它缓解了IPv4地址不足的问题,但也给网络带来了复杂性和脆弱性。NAT的普及延缓了IPv6的普及,并对P2P通信造成了困扰。--GPT 4

network

How to fix some issues while using "diesel"

If you encounter the 'cannot open input file "sqlite3.lib"' error when operating sqlite file with Diesel, don't worry, it's because Diesel can't find the file sqlite3.lib at the path ~/.rustup/toolchains/..... You can download sqlite3.lib from the link provided in the article. After downloading, unzip it and move sqlite3.lib to the path ~/.rustup/toolchains/stable-x86_64-pc-windows-msvc/lib/rustlib/x86_64-pc-windows-msvc/lib/. Note that the path might be different if you use a different version of Rust. This article provides a simple solution to the error and helps you get back on track with your work.--GPT 4

Rust

Leptos - CSR & SSR

Leptos是一个全栈框架,支持MVC式的Web应用开发。前端框架的纯前端应用采用CSR(客户端渲染)方式,优点是更少的打包文件,更紧凑的格式,但对SEO不友好。SSR(服务器端渲染)是更好的选择,Leptos采用Actix和Axum实现SSR,分为脱水、浸泡和湿润三个步骤,使用Rust的features在不同环境运行不同代码。组件里的服务器代码运行在SSR环境下,Leptos提供了Server Functions功能,可以在组件里使用服务器的代码。但是,Leptos的SSR环境有时会遇到一些奇怪的问题。--GPT 4

Rust Leptos

Rust 和经典语言在习惯上的差异

本文介绍了 Rust 和 C# 在编程习惯上的差异。首先介绍了 Rust 中的所有权概念,即变量持有它的值的所有权、变量赋值给别的变量会转移所有权、变量不能使用它没有持有所有权的值。这种概念带来的好处是严格限制了值的生命周期,为编译器知道在何处释放它提供了基础。其次,本文介绍了 Rust 中的抽象,即单元结构体的使用方法,它不定义任何的属性,可以用 `impl` 块给他定义方法,调用的时候单元结构体的名字提供了抽象。最后,本文介绍了在 Rust 中经常出现的嵌套泛型的写法,这种写法是为了实现动态分配,而其他的,如 `Mute<T>` 和 `Arc<T>` 是为了在多线程中共享数据。在 Rust 中必须要习惯这种 **wrap** 写法。--GPT 4

Rust

Leptos - 撸一只赛博猫猫

本文介绍了使用Leptos和Rust语言,替代Javascript,编写一个可爱的赛博猫猫动画的过程。文章首先介绍了一些有用的crates,如console_log、gloo和js-sys,它们分别提供了打印输出、大量BOM调用的API和时间库功能。然后,作者详细描述了如何使用HTML和Rust编写的逻辑代码,包括事件监听和类似Javascript的Interval时间函数,来创建一个可交互的赛博猫猫动画。此外,文章还详细解释了如何使用Interval时间函数和数组存储的字符画,来实现猫猫摇尾巴的动画效果。最后,作者提到了如何使用on_cleanup函数,在组件清理的时候取消Interval函数,以及如何在组件卸载的时候清理Interval。那么,如何使用Rust和Leptos来创建自己的动画呢?你会尝试使用这些方法和技巧来创建自己的项目吗?--GPT 4

Rust

从实现 Iterator 来窥探 Rust

本文详细介绍了如何在Rust中实现Iterator trait,以支持for in遍历。首先,我们定义了一个简单的struct,然后实现了一个iter()方法,将其转换为另一个实现了Iterator trait的结构。接下来,我们探讨了为何不直接在Nums上实现Iterator,以及Rust特有的生命周期标注的概念。我们还解释了如何在NumsIter结构中使用生命周期标注,以保证在借用Nums的时间内Nums都是存在的。最后,我们实现了Iterator trait,并给出了完整的代码示例。这篇文章提供了一个深入理解Rust中Iterator实现和生命周期标注的好机会。那么,你是否已经理解了如何在Rust中实现Iterator?你是否理解了生命周期标注的作用及其在Rust中的重要性?--GPT 4

Rust

Leptos 初探 - 序言

Leptos是一个用Rust开发的全栈Web框架,其写法类似于React,但实现机制却大相径庭。Leptos采用最小粒度更新的方式,避免了虚拟DOM的处理,性能上优于React。然而,由于Rust语言的学习难度,Leptos的普及可能会受到一定限制。此外,Leptos的更新机制依赖于闭包,而Rust严苛的语法规则可能会给开发者带来一些挑战。例如,Rust的所有权规则需要通过`Rc`进行引用计数来解决。最后,Leptos的代码最终会编译到浏览器的WASM环境中运行,因此不是所有的Rust crate都能够正常运行,需要挑选能够在WASM中使用的crate。这篇文章对Leptos的使用进行了详细的介绍,对于想要了解和使用Leptos的开发者来说,具有一定的参考价值。那么,你是否已经准备好接受Leptos的挑战,使用Rust开发你的Web应用呢?--GPT 4

Rust Leptos

滑动窗口最大值

本篇博客详细解析了Leetcode上的一道题目——滑动窗口最大值。该题目要求从一个整数数组中,通过滑动窗口的方式,获取每个窗口中的最大值。博客首先介绍了题目的要求和示例,然后提出了一种直接的解决方法,即通过for循环遍历数组,对窗口中的子数组进行排序,获取最大值。但是这种方法的时间复杂度较高,无法满足题目要求。因此,博客提出了一种新的解决方法,即通过队列获取窗口中的最大值。在遍历数组的过程中,将遍历到的值加入队列,然后比较队列尾部的值和当前值,如果队列尾部的值小于当前值,就从队列中删除尾部的值,直到尾部的值大于当前值或队列为空,然后将当前值放入队列尾部。这样可以保证队列头部的值始终是窗口中的最大值。随着遍历的进行,如果队列头部的值不在窗口内,就将头部的值移出。这种方法的时间复杂度较低,能够满足题目要求。博客通过详细的代码示例,对这种解决方法进行了深入的解析和讲解。这种解决方法是否适用于所有的滑动窗口问题呢?如果窗口的大小不固定,这种方法还能否有效?--GPT 4

Algorithms

湘伦小雨四手联弹 - 低音部分和弦走向分析

本篇博客主要分析了湘伦小雨四手联弹的低音部分和弦走向。通过详细的音符、和弦图示和讲解,我们可以清晰地了解到这首曲子的和弦结构和旋律走向。博客首先通过调号确定了曲目的主调为E小调,然后逐小节分析了和弦的变化和功能,包括主调的确定、过渡和终止等。分析过程中,博客还详细解释了和弦的级数和构成,以及各级和弦在曲目中的作用和意义。例如,前三个小节的E下行B交替,组成了E小调i级和弦,起到明确主调的作用;第四小节的#C -> #D起过渡作用,过度到第五小节的E。之后的和弦走向为i -> V -> i -> iv -> i,构成了曲目的基本骨架。整个分析过程严谨细致,充满音乐理论知识,对于理解和学习这首曲目有着极大的帮助。你能否从这篇博客中找到音乐理论和实践相结合的魅力?你又能否从中感受到和弦在音乐中的重要作用,以及如何通过和弦分析理解和学习音乐作品?--GPT 4

music

Multiaddr - 面向未来的地址

本文详细介绍了Multiaddr这一面向未来的网络地址方式。Multiaddr以更加友好的方式描述网络地址,包含了比传统网络地址更多的信息,例如网络协议、加密协议等。它以人类可读、机器可读的形式存在,可以轻易地在机器中表示为二进制形式。然而,尽管Multiaddr的可读性较好,但它增加了程序实现的复杂性。使用Multiaddr的程序需要自己解析其中的协议,这会增加程序的工作量。此外,Multiaddr对于程序的耦合性较差,实际开发过程中可能不如传统方式。因此,尽管Multiaddr是一种有趣的地址方式,但由于没有配套的成套工具,且造轮子的成本高,作者并不推荐使用。那么,你对Multiaddr有什么看法呢?你认为它的优点能否弥补其缺点,使其在未来得到广泛应用?--GPT 4

network