首页
友情链接
关于
推荐
工具
Linux
Search
1
欢迎使用 Typecho
20,688 阅读
2
(Windows)以一种访问权限不允许的方式做了一个访问套接字的尝试处理
3,674 阅读
3
Playwright使用记录
3,545 阅读
4
Unity独立安装后添加IL2CPP等编译组件
2,771 阅读
5
Windows上GCC安装
2,508 阅读
全部博文
游戏开发
Unity
Godot Engine
GDScript
编程代码
C#编程
GoLang编程
PowerShell
开发工具
Git
笔记备忘
登录
Search
标签搜索
docker
Godot
GCC
CMS
Proto.Actor
Actor模型
winpty
msys2
Unity
IL2CPP
package
golang
ssh
proxy
proxychains
minikube
k8s
n2n
PowerShell
ChatGPT
玖亖伍
累计撰写
33
篇文章
累计收到
221
条评论
首页
栏目
全部博文
游戏开发
Unity
Godot Engine
GDScript
编程代码
C#编程
GoLang编程
PowerShell
开发工具
Git
笔记备忘
页面
友情链接
关于
推荐
工具
Linux
搜索到
4
篇与
的结果
2024-08-23
Blazor CSS 隔离要点
ASP.NET Core Blazor CSS 隔离起因在 Blazor 组件(Components)/页面(Pages)中, 难免有自定义的样式需要设置,查询 ASP.NET Core Blazor 文档后,发现了 CSS 隔离,但是反复尝试终不生效。解决经过多方搜索后,找到了解决方案,发现是使用方式不对,Blazor CSS 隔离 要求 使用 css class 的组件必须在 HTML 原生 Tag 内,所以需要将 Blazor 放到原生 HTML Tag 中。完整步骤如下:以基于 MudBlazor 的项目为例, 假设项目名为 WebUI创建 Page (例: Components/Pages/Demo.razor)@page "/demo" <PageTitle>Demo</PageTitle> <MudText Typo="Typo.body2" class="custom-text">Vector</MudText>创建 隔离 CSS 文件 (例: Components/Pages/Demo.razor.css)::deep .custom-text { color: #fa1; font-size: 1.5rem; }在 Components/App.razor 中 <head> </head> 之间添加如下代码, 引用 CSS 隔离 bundle 文件:<link href="@(nameof(WebUI)).styles.css" rel="stylesheet" />这是发现是无效的,需要将 Page 中的 <MudText class="custom-text" ... 放到 HTML Tag 中(比如 div`), 修改后如下:@page "/demo" <PageTitle>Demo</PageTitle> <div> <MudText Typo="Typo.body2" class="custom-text">Vector</MudText> <div>再次运行即可生效。注意: 编辑 css 文件后若重新运行未生效,可以尝试 Ctrl + F5 刷新缓存。参考 MudAutoComplete - CSS Isolation of .mudpopover #1606As I told you, you need to wrap the component in an html element, for example, in a div<div> <MudPaper> <MudAutocomplete/> </MudPaper> </div>And then in your MyComponent.razor.css file, put your css code with deep::deep .mud-popover { width: 600px !important; background-color: aliceblue !important; }
2024年08月23日
18 阅读
0 评论
1 点赞
2021-08-12
.Net(C#)常用开源库
Actor框架名字开源地址NuGet主站点中文站点Proto.ActorAsynkronIT/protoactor-dotnetProto.Actorproto.actor Akka.NETakkadotnet/akka.netAkkagetakka.net Orleansdotnet/orleansMicrosoft.Orleans.Coredotnet.github.io/orleansorleans.azurewebsites.netactors-actorsvlingo-net/xoom-net-actorsVlingo.Xoom.Actors 网络库名字开源地址NuGet协议支持C/S端主站点SpanNettycuteant/SpanNettySpanNetty.HandlersTCP、UDP、HTTP、HTTP2、WebSocketC、S LiteNetLibRevenantX/LiteNetLibLiteNetLibRUDPC、Srevenantx.github.io/LiteNetLibTelepathyvis2k/TelepathyTelepathyTCPC、S NetCoreServerchronoxor/NetCoreServerNetCoreServerTCP、UDP、HTTP、WebSocketC、Schronoxor.github.io/NetCoreServerWatsonTcpjchristn/WatsonTcpWatsonTcpTCPC、S websocket-sharpsta/websocket-sharpWebSocketSharpWebSocketC、Ssta.github.io/websocket-sharpEmbedIOunosquare/embedioEmbedIOHttp、WebSocketSunosquare.github.io/embedio
2021年08月12日
957 阅读
0 评论
0 点赞
2021-08-02
Playwright使用记录
Playwright for .NET is the official language port of Playwright, the library to automate Chromium, Firefox and WebKit with a single API.操作记录# 安装 Playwright 工具 dotnet tool install --global Microsoft.Playwright.CLI # 创建项目 dotnet new console -n PlaywrightDemo cd PlaywrightDemo # 安装依赖 dotnet add package Microsoft.Playwright --prerelease # 用Playwright 工具安装浏览器 playwright install # chromium v888113 downloaded to C:\Users\gsw\AppData\Local\ms-playwright\chromium-888113 # firefox v1268 downloaded to C:\Users\gsw\AppData\Local\ms-playwright\firefox-1268 # webkit v1490 downloaded to C:\Users\gsw\AppData\Local\ms-playwright\webkit-1490 # ffmpeg v1005 downloaded to C:\Users\gsw\AppData\Local\ms-playwright\ffmpeg-1005 # 运行项目(PlaywrightDemo) dotnet run # 自动生成代码 playwright codegen # 打开指定页面(可调试或生成代码) playwright open https://gsw945.com/ # 以指定的语言、时区、和窗口大小,使用chromium浏览器打开指定页面,生成C#代码 playwright codegen --target csharp --browser chromium --channel chrome --lang "zh-CN" --timezone "Asia/Shanghai" --viewport-size "1920,1080" "https://gsw945.com/"代码示例using Microsoft.Playwright; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; class Program { /// <summary> /// 等待退出 /// </summary> private static ManualResetEvent waitQuitEvent = new ManualResetEvent(initialState: false); public static async Task Main() { // 设置调试相关环境变量 Environment.SetEnvironmentVariable("PWDEBUG", "console"); Environment.SetEnvironmentVariable("DEBUG", "pw:api"); var appDataLocal = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); Console.WriteLine($"playwright下载浏览器目录: {Path.Combine(appDataLocal, "ms-playwright")}"); List<KeyValuePair<string, string>> envs = new List<KeyValuePair<string, string>>(); foreach (DictionaryEntry envItem in Environment.GetEnvironmentVariables()) { envs.Add(new KeyValuePair<string, string>((string)envItem.Key, (string)envItem.Value)); } // 创建playwright实例 using var playwright = await Playwright.CreateAsync(); // 创建Chromium浏览器实例 await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions() { Headless = false, // 关闭无头模式(有界面) Channel = "chrome", // 指定采用chrome浏览器类型 Devtools = true, // 启用开发者工具 ChromiumSandbox = false, // 关闭浏览器沙盒 Env = envs, // 环境变量 ExecutablePath = string.Empty, // 不指定浏览器可执行文件位置,会自动寻找 ms-playwright 下载的浏览器 }); browser.Disconnected += (object sender, IBrowser e) => { Console.WriteLine($"On Browser Close"); }; // 浏览器上下文 await using var context = await browser.NewContextAsync(new BrowserNewContextOptions { ViewportSize = new ViewportSize { Width = 1536, // 1920 * 0.8 Height = 864, // 1080 * 0.8 }, // 视口大小 Locale = "zh-CN", // 语言(区域) TimezoneId = "Asia/Shanghai", // 时区 }); context.Close += (object sender, IBrowserContext e) => { Console.WriteLine($"On Context Close"); }; // 新开页面(空白页) var page = await context.NewPageAsync(); // var page = await browser.NewPageAsync(); page.Close += (object sender, IPage e) => { Console.WriteLine($"On Page Close"); }; page.Dialog += async (_, dialog) => { Console.WriteLine(dialog.Message); await dialog.DismissAsync(); }; // 新开的页面跳转(打开)到指定URL await page.GotoAsync("https://gsw945.com/"); // await page.GotoAsync("https://playwright.dev/dotnet"); // 当前页面截图并保存到指定位置 var screenshotPath = Path.GetFullPath("screenshot.png"); await page.ScreenshotAsync(new PageScreenshotOptions { Path = screenshotPath, FullPage = true, Type = ScreenshotType.Png, OmitBackground = true }); if (File.Exists(screenshotPath)) { Console.WriteLine($"页面截图: {screenshotPath}"); // File.Delete(screenshotPath); } // (通过css选择器选择)点击指定的元素(如果元素还未出现在DOM中则等待) // refer: https://playwright.dev/dotnet/docs/core-concepts#auto-waiting await page.ClickAsync("a[title=\"友情链接\"]"); // (通过css选择器选择)等待元素出现在DOM中 await page.WaitForSelectorAsync("#Joe_Baidu_Record"); // 执行javascript表达式并取得结果 // refer: https://playwright.dev/dotnet/docs/core-concepts#execution-contexts-playwright-and-browser var href = await page.EvaluateAsync<string>("document.location.href"); Console.WriteLine($"href: {href}"); // 普通逻辑, 等待console退出 await StartWait2Exit(context); } public static async Task StartWait2Exit(IBrowserContext context) { Console.WriteLine("-".PadLeft(60, '-')); Console.WriteLine("Press [Ctrl + C] or [Q] or [Esc] to quit..."); Console.WriteLine("-".PadLeft(60, '-')); // Ctrl + C 捕获 Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs eventArgs) => { eventArgs.Cancel = true; Console.WriteLine("[Ctrl + C] pressed, to quit."); waitQuitEvent.Set(); }; Thread t = new Thread(() => { while(true) { // 监听是否关闭了浏览器(playwright 断开连接 或 所有打开的页面全部都关闭了) if (!context.Browser.IsConnected || context.Pages.Count < 1) { Console.WriteLine("Detect Browser Context Is Not Connected or No Page is Open"); } // 如果输入输出未重定向 if (!Console.IsInputRedirected && Console.KeyAvailable) { // 读取键盘输入 ConsoleKeyInfo keyInfo = Console.ReadKey(intercept: true); Console.WriteLine($"Key: {keyInfo.Key}"); // Q或ESC键,退出 if (keyInfo.Key == ConsoleKey.Q || keyInfo.Key == ConsoleKey.Escape) { break; } } Thread.Sleep(millisecondsTimeout: 50); } waitQuitEvent.Set(); }); t.IsBackground = true; t.Start(); waitQuitEvent.WaitOne(); await Task.Yield(); } }参考Getting Started | PlaywrightDebugging toolsPlaywright for .NETPlaywrightBrowserBrowserContextPagePage.ScreenshotAsync(options)Page.WaitForSelectorAsync(selector, options)https://github.com/microsoft/playwrighthttps://github.com/microsoft/playwright-dotnet
2021年08月02日
3,545 阅读
0 评论
1 点赞
2021-07-29
Proto.Actor Bootcamp 学习笔记
Proto.Actor Bootcamp一、介绍Actor模型和Proto.Actor1. 为何使用Actor模型源: Docs\Bootcamp\Unit 1\Lesson 1: Why use the actor model无需手动控制线程高级抽象垂直伸缩(扩大)水平伸缩(扩展)容错和错误处理常见的体系结构2. Actor模型适用的应用类型源: Docs\Bootcamp\Unit 1\Lesson 2: Types of applications for which actors are suitable.交易应用可分包的应用服务通信应用多人游戏交通管理数值处理物联网3. Proto.Actor在不同类型的应用中的使用源: Docs\Bootcamp\Unit 1\Lesson 3: Use of Proto.Actor in different types of applications.服务端服务后端(Web Api等)Web应用客户端控制台应用WPF应用4. 反应式编程宣言源: Docs\Bootcamp\Unit 1\Lesson 4: The Reactive ManifestoProto.Actor 遵循反应式编程宣言事件驱动弹性伸缩容错恢复响应性5. Proto.Actor的关键特性源: Docs\Bootcamp\Unit 1\Lesson 5: Key features of the Proto.Actor.并发和异步分布式处理高性能容错在单个应用程序使用多种编程语言的能力6. Actor和消息源: Docs\Bootcamp\Unit 1\Lesson 6: Actors and messages.Actor之间通过消息进行交互消息是异步的7. Proto.Actor中Actor是什么源: Docs\Bootcamp\Unit 1\Lesson 7: What’s an actor in Proto.Actor.一切都是Actor遵循 单一功能原则(Single responsibility principle)Actor功能接收消息并处理创建更多的Actor给其他Actor发消息改变状态以便可以处理后续消息Actor包括State 状态Behavior 行为对接收到的消息的处理Mailbox 信箱默认先入先出(FIFO)可用算法控制优先级Child actors 子级Actorcontext.actorOf (...) 创建context.stop (child) 停止Supervisor strategy 监管策略重启子级Actor,保持子级Actor的状态重启子级Actor,恢复子级Actor到标准状态停止子级Actor传递错误到父级Actor8. Proto.Actor中消息是什么源: Docs\Bootcamp\Unit 1\Lesson 8: What’s a message in Proto.Actor.Actor之间传递的数据(可以是普通的类)消息(在创建后)是不可变的消息是线程安全的9. Proto.Actor中Props、RootContext和ActorContext分别是什么源: Docs\Bootcamp\Unit 1\Lesson 9: What’re Props, RootContext, and ActorContext in Proto.Actor.RootContext 创建初始(顶级)Actor, 和应用系统中的Actor交互ActorContext 创建(普通, 非顶级)Actor, 和其他Actor交互, 存储Actor相关的数据Props 一个配置类, 设置创建Actor的参数10. Proto.Actor监管层级概述源: Docs\Bootcamp\Unit 1\Lesson 10: Overview of the supervisor hierarchy in Proto. Actor.错误处理自我修复11. 安装Proto.Actor源: Docs\Bootcamp\Unit 1\Lesson 11: Installing Proto.Actor.Proto. Actor 主要的NuGet包Proto.Schedulers.SimpleScheduler 调度消息(延迟发送或间隔重复发送等)Proto.Persistence.* 持久化Actor状态Proto.Remote 远程Proto.Cluster.* 集群Proto.OpenTracing 追踪和调试Actor二、 Actor和消息的定义和使用1. 定义Actor源: Docs\Bootcamp\Unit 2\Lesson 1: Defining Actors.一个继承自Proto.Actor的Actor基类的类定义可以处理的消息类型确保Actor的内部状态不会被其他Actor改变一个Actor的功能应该足够简单,如果太负责则应该拆分为单独的Actor注意Actor使用的计算资源和内存消耗2. Actor引用源: Docs\Bootcamp\Unit 2\Lesson 2: Actor References.PID 区分Actor, Actor的抽象层唯一增量分配Actor之间通过PID通信3. 定义消息源: Docs\Bootcamp\Unit 2\Lesson 3: Defining Messages.使用C#创建消息普通C#类类属性外部只读Protocol Buffers (protobuf)字段唯一编号1~536870911 取值区间19000~19999 保留值区间(内部使用)1~15 占用1个字节16~2047 占用2个字节option csharp_namespace 定义生成的C#代码的namespacepackage 防止消息定义命名冲突4. 发送消息的类型:源: Docs\Bootcamp\Unit 2\Lesson 4: Types of Message Sending.Send() 发送消息, 无需等待响应, 性能消耗小RequestAsync() 发送消息, 等待响应, 可设置等待超时Forward() 转发收到的消息到其他Actor5. Actor实例化:源: Docs\Bootcamp\Unit 2\Lesson 5: Actor Instantiation.6. 定义Actor将要处理的消息:源: Docs\Bootcamp\Unit 2\Lesson 6: Defining Which Messages an Actor will processing.7. 发送自定义消息:源: Docs\Bootcamp\Unit 2\Lesson 7: Sending a Custom Message.三、 理解Actor的生命周期和状态1. Actor生命周期源: Docs\Bootcamp\Unit 3\Lesson 1: Actor Lifecycle.Actor生命周期状态Starting ProcessMessageAsync()Receiving MessagesStopping产生原因:调用 ActorContext.Stop() 或 ActorContext.StopAsync()子级Actor出现错误,父级Actor会发送停止消息给它状态拆分:Stopping 收到Stop消息, 准备停止Stop Actor已停止, 使用的资源已释放Restarting 停止之后, 收到Restart消息Terminated 收到Terminated消息, 不再接受任何消息, 不能被重新加载2. Actor生命周期消息源: Docs\Bootcamp\Unit 3\Lesson 2: Actor Lifecycle Messages.3. 终止Actor和Actor的层次结构源: Docs\Bootcamp\Unit 3\Lesson 3: Terminating Actors and Hierarchy of Actors.4. PoisonPill消息及其用法源: Docs\Bootcamp\Unit 3\Lesson 4: What is the Poison Pill message and how to work with it.5. 可切换的Actor行为源: Docs\Bootcamp\Unit 3\Lesson 5: Switchable Actor Behavior.Behavior 运行时动态修改Actor的行为Become() 清空行为栈,添加行为BecomeStacked() 不清空行为栈,追加行为ReceiveAsync(context) 消息处理6. 使用行为切换重构源: Docs\Bootcamp\Unit 3\Lesson 6: Refactoring with using behavior switching.四、 创建Actor层级和错误处理1. 监控和Actor层级源: Docs\Bootcamp\Unit 4\Lesson 1: Supervisor and actor hierarchy.system.Root.Spawn(props); 创建顶级(Actor)Actorcontext.Spawn(props); 创建子级Actor2. 演示监控者的能力和Actor层级的应用概览源: Docs\Bootcamp\Unit 4\Lesson 2: Overview of the application that demonstrates the supervisor’s capabilities and the actors hierarchy.3. Actor的地址和PID源: Docs\Bootcamp\Unit 4\Lesson 3: Actor’s address and PID.$"{system.ProcessRegistry.NextId()}/{name}" PID格式var moviePlayCounterActorPid = new PID(system.ProcessRegistry.Address, "$1/MoviePlayCounterActor"); 手动创建PID4. 创建 UserCoordinatorActor源: Docs\Bootcamp\Unit 4\Lesson 4: Creating UserCoordinatorActor.5. 创建 MoviePlayCounterActor源: Docs\Bootcamp\Unit 4\Lesson 5: Creating MoviePlayCounterActor.6. 父级Actor如何监管他们的子级Actor源: Docs\Bootcamp\Unit 4\Lesson 6: How parent actors are watching over their children actors.继续处理(忽略错误)重启完全停止委托上层Actor处理7. 控制子级Actor的策略源: Docs\Bootcamp\Unit 4\Lesson 7: Strategies to control the state of children’s actors.WithChildSupervisorStrategy() 重写子级Actor监控策略public delegate SupervisorDirective Decider(PID pid, Exception reason); Decider委托OneForOneStrategy 仅仅产生异常的子级Actor会执行从Decider()方法收到的指令(Directive)AllForOneStrategy 所有的子级Actor都会执行从Decider()方法收到的指令(Directive)五、 消息路由使用路由控制消息流:性能 (使用Proto.Actor路由)消息内容 (使用常规Actor)状态1. 路由模式源: Docs\Bootcamp\Unit 5\Lesson 1: Router pattern.性能收到不同内容的消息取决于路由的状态2. 利用Proto.Actor路由负载均衡源: Docs\Bootcamp\Unit 5\Lesson 2: Load balancing with Proto.Actor routers.两种内置路由类型:Pool 负责Actor的创建和完成后的移除,是Actor的父级ActorGroup 不参与Actor的创建,与Actor的层级结构无关几个内置路由:Round-robin 顺序发送消息到ActorHash key 消息携带地址Random 随机选择接收者Weighted round robin 和Round-robin类似,但支持为特定的接收者定制权重Broadcast 消息发给组里面的所有Actor3. 路由池源: Docs\Bootcamp\Unit 5\Lesson 3: Pool Router.路由创建远程路由 - 特殊消息:RouterAddRoutee 将本地Actor或远程Actor的PID添加到路由表中RouterRemoveRoutee 从路由表中移除PIDRouterGetRoutees 获取(当前路由器)使用的路由表Routees 包含当前(路由器的)路由表状态检测4. 路由组源: Docs\Bootcamp\Unit 5\Lesson 4: Group Router.组创建5. 一致性哈希路由源: Docs\Bootcamp\Unit 5\Lesson 5: ConsistentHashing Router.将消息(Message)转换为消息键(Message Key)对象。IHashable接口基于消息键(Message Key)创建散列码(Hash Code)根据哈希码(Hash Code)选择虚拟主机(Virtual host)发送消息到选择的虚拟主机6. 使用Actor实现路由模式源: Docs\Bootcamp\Unit 5\Lesson 6: Implementation of the router pattern with using actors.根据内容路由基于状态路由六、 消息通道1. 通道类型源: Docs\Bootcamp\Unit 6\Lesson 1: Channels Types.point-to-point, 连接发送者(sender)和接受者(recipient)publisher/subscriber, 可运行期间动态改变接受者,实现EventStream类2. 点对点通道源: Docs\Bootcamp\Unit 6\Lesson 2: Point-to-point Channel.每条消息只会发给某一个接收者发送者知道接收者3. 发布/订阅通道源: Docs\Bootcamp\Unit 6\Lesson 3: Publisher/Subscriber Channel.单条消息可以发送给多个接收者发送者不关心接收者是谁4. 事件流源: Docs\Bootcamp\Unit 6\Lesson 4: EventStream.Subscribe<T>()Unsubscribe()Publish(msg)5. 死信(无法投寄的信)源: Docs\Bootcamp\Unit 6\Lesson 5: DeadLetter Channel.6. 保证投递源: Docs\Bootcamp\Unit 6\Lesson 6: Guaranteed delivery.七、Proto.Actor远程1. 水平伸缩是什么源: Docs\Bootcamp\Unit 7\Lesson 1: What is horizontal scaling.典型网络拓扑Bus 总线Star 星形Ring 环形Mesh 网状Tree 树形Point-to-Point 点对点2. Proto.Actor远程概览源: Docs\Bootcamp\Unit 7\Lesson 2: Overview Proto.Actor Remote.Proto.Remote关键特性位置透明(Location transparency)远程创建(Remote spawning)gRPC流(gRPC Streams)3. Proto.Actor远程使用示例源: Docs\Bootcamp\Unit 7\Lesson 3: Example of working with Proto.Actor Remote.八、Proto.Actor集群1. 为什么你需要集群源: Docs\Bootcamp\Unit 8\Lesson 1: Why do you need clusters.2. 集群中的成员源: Docs\Bootcamp\Unit 8\Lesson 2: Membership in the cluster.3. 加入集群源: Docs\Bootcamp\Unit 8\Lesson 3: Joining to the cluster.分布式架构中,服务发现的功能集群中的元信息服务的一致性注册和监控组件可用性的机制组件发现的机制服务发现Proto.Cluster.ConsulProto.Cluster.SingleRemoteInstance4. 在集群中处理任务源: Docs\Bootcamp\Unit 8\Lesson 4: Processing tasks in the ClusterTODO: 学习记录, 此处继续
2021年07月29日
511 阅读
0 评论
0 点赞