Go Ble开发实战

⚠️代码仅最后部分进行了测试,前面的暂未测试 1. 简介 BLE (Bluetooth Low Energy) 是一种低功耗蓝牙技术。Go-BLE 是 Go 语言的 BLE 库,提供了简单易用的 API 来开发 BLE 应用。本文将通过一个完整的示例来展示如何使用 Go-BLE 创建一个蓝牙服务器。 Go-BLE 主要支持 Linux 和 macOS 平台(1),但需要注意 macOS 部分目前并未被积极维护。 2. 环境准备 2.1 安装依赖 # 安装 go-ble go get -u github.com/go-ble/ble # 安装设备支持库 go get -u github.com/go-ble/ble/examples/lib/dev # Linux系统需要设置权限 sudo setcap 'cap_net_raw,cap_net_admin+eip' ./your_program 3. BLE基础概念 3.1 核心概念 Peripheral (外围设备):提供服务的设备 Central (中心设备):连接外围设备的设备(如手机) Service (服务):功能的集合 Characteristic (特征):具体的数据点 Descriptor (描述符):特征的元数据 3.2 常见的 UUID 标准服务 UUID: 电池服务:0x180F 设备信息服务:0x180A 心率务:0x180D 标准特征 UUID: 电池电量:0x2A19 设备名称:0x2A00 制造商名称:0x2A29 型号名称:0x2A24 序列号:0x2A25 固件版本:0x2A26 信号强度:0x2A1C 自定义 UUID 生成: // 使用在线工具生成 UUID v4 svcUUID := ble....

使用 Suture在Go中实现可靠的监督树

简介 在构建复杂的分布式系统时,我们常常需要面对各种意外情况,如服务崩溃、网络中断等。为了提高系统的可靠性和容错能力,监督树模式应运而生。Suture 是一个受 Erlang OTP 框架启发的 Go 语言监督树库,它为 Go 开发者提供了一种优雅的方式来管理和监控长时间运行的服务。 监督树的核心思想是将系统组织成一个树状结构,其中父节点(监督者)负责监控和管理子节点(工作者)。当子节点发生故障时,父节点可以根据预定策略进行重启或其他恢复操作,从而提高系统的整体稳定性。 Suture 的核心概念 Suture 的设计围绕以下几个核心概念: Service 接口: 定义了可被监督的服务应该实现的方法。 Supervisor 结构体: 代表一个监督者,负责管理一组服务。 重启策略: 定义了当服务失败时,监督者应该如何响应。 安装和基本使用 首先,通过以下命令安装 Suture: go get github.com/thejerf/suture/v4 然后,在你的 Go 代码中导入 Suture: import "github.com/thejerf/suture/v4" 创建一个简单的 Service: type MyService struct{} var _ suture.Service = (*MyService)(nil) func (s *MyService) Serve(ctx context.Context) error { for { select { case <-ctx.Done(): return nil default: // 执行服务逻辑 time.Sleep(time.Second) fmt.Println("Service is running") } } } 设置 Supervisor 并添加 Service:...

rust中map_error的用法

Rust中的map_err方法是Result类型的一个方法,用于转换错误类型。它允许你在保持Ok值不变的情况下,修改Err值。这在错误处理和类型转换中非常有用。 以下是map_err的详细用法和一些例子: 基本用法 fn main() -> Result<(), String> { let result: Result<i32, &str> = Err("原始错误"); let mapped = result.map_err(|e| e.to_string()); mapped } 在这个例子中,我们将&str类型的错误转换为String类型。 链式调用 use std::num::ParseIntError; fn parse_and_multiply(s: &str) -> Result<i32, String> { s.parse::<i32>() .map_err(|e: ParseIntError| e.to_string()) .map(|n| n * 2) } fn main() { match parse_and_multiply("10") { Ok(n) => println!("结果: {}", n), Err(e) => println!("错误: {}", e), } match parse_and_multiply("abc") { Ok(n) => println!("结果: {}", n), Err(e) => println!("错误: {}", e), } } 这个例子展示了如何在解析字符串并进行计算的过程中使用map_err转换错误类型。...

Rust derive_builder快速使用参考

derive_builder是 简化Rust结构体构建的强大工具,本文使用claude 3.5 生成 1. 引言 在Rust编程中,创建复杂的结构体实例常常需要大量的样板代码。derive_builder 是一个强大的过程宏库,它可以自动为结构体生成 builder 模式的实现,大大简化了结构体的创建过程。本文将深入介绍 derive_builder 的使用方法、特性和最佳实践。 2. 基本用法 2.1 安装 首先,在你的 Cargo.toml 文件中添加 derive_builder 依赖: [dependencies] derive_builder = "0.20.0" 2.2 简单示例 让我们从一个简单的例子开始: use derive_builder::Builder; #[derive(Builder, Debug)] struct Server { host: String, port: u16, } fn main() { let server = ServerBuilder::default() .host("localhost".to_string()) .port(8080) .build() .unwrap(); println!("{:?}", server); } 在这个例子中,我们为 Server 结构体派生了 Builder 特征。这会自动生成一个 ServerBuilder 结构体,它提供了流畅的 API 来构建 Server 实例。 3. 字段属性 derive_builder 提供了多种属性来自定义字段的行为。...

Rust serde_with快速参考

serde_with 是 Rust 中 serde 序列化/反序列化库的一个扩展,提供了许多有用的自定义序列化和反序列化方法。以下是一些常用的功能和适用场景: 字符串格式化 use serde_with::rust::display_fromstr; #[derive(Serialize, Deserialize)] struct Foo { #[serde_with(as = "display_fromstr")] bar: u32, } 适用于需要将数字类型序列化为字符串的场景。 时间格式化 use serde_with::chrono::datetime_utc_ts_seconds_from_any; #[derive(Serialize, Deserialize)] struct Foo { #[serde_with(as = "datetime_utc_ts_seconds_from_any")] time: DateTime<Utc>, } 适用于需要自定义时间格式的场景。 枚举字符串表示 use serde_with::{serde_as, DisplayFromStr}; #[serde_as] #[derive(Serialize, Deserialize)] struct Foo { #[serde_as(as = "DisplayFromStr")] bar: MyEnum, } 适用于将枚举序列化为字符串的场景。 跳过序列化默认值 use serde_with::skip_serializing_none; #[skip_serializing_none] #[derive(Serialize)] struct Foo { bar: Option<String>, } 适用于需要在序列化时忽略 None 值的场景。 自定义序列化/反序列化 use serde_with::{serde_as, FromInto}; #[serde_as] #[derive(Serialize, Deserialize)] struct Foo { #[serde_as(as = "FromInto<String>")] bar: MyCustomType, } 适用于需要为自定义类型实现序列化/反序列化的场景。...

在rust中使用protobuf

常规方式 安装必要工具 # 安装 protoc # 在 macOS 上: brew install protobuf # 在 Ubuntu 上: sudo apt-get install protobuf-compiler # 安装 Rust protobuf 代码生成器 cargo install protobuf-codegen 示例 创建一个protobuf的文件: message.proto syntax = "proto3"; package mypackage; message Person { string name = 1; int32 age = 2; string email = 3; } 然后执行命令 protoc --rust_out=. message.proto 如果是在项目中,在你的 Rust 项目中,添加必要的依赖到 Cargo.toml: [dependencies] protobuf = "2.27.1" 然后可以在代码中访问生成的内容 use protobuf::Message; mod message; // 引入生成的模块 use message::Person; fn main() { let mut person = Person::new(); person....

在go中使用CoAP

CoAP协议 CoAP(Constrained Application Protocol)是一种专为物联网(IoT)和受限环境设计的网络协议。它的主要目标是为资源受限的设备(如传感器、执行器等)提供一种轻量级的通信方式。以下是 CoAP 协议的几个关键特点和功能: 1. 轻量级设计 小开销:CoAP 使用 UDP(用户数据报协议)作为传输层,相比于 TCP(传输控制协议),它具有更小的头部开销,适合带宽有限的环境。 简化的消息格式:CoAP 消息格式简单,适合资源受限的设备。 2. 请求/响应模型 类似 HTTP:CoAP 采用类似于 HTTP 的请求/响应模型,客户端可以发送请求(如 GET、POST、PUT、DELETE)来与服务器交互。 资源导向:CoAP 允许客户端访问和操作服务器上的资源,资源通过 URI(统一资源标识符)进行标识。 3. 可靠性 确认机制:虽然 CoAP 基于 UDP,但它实现了可靠性机制,包括重传和确认,以确保消息的可靠传输。 非确认和确认消息:CoAP 支持两种类型的消息:确认消息(需要确认)和非确认消息(不需要确认),以适应不同的应用需求。 4. 观察功能 资源观察:CoAP 支持观察功能,允许客户端订阅资源的变化,当资源状态发生变化时,服务器会主动通知客户端。这减少了轮询请求的需要。 5. 多播支持 多播通信:CoAP 原生支持多播,允许服务器向多个客户端同时发送消息,适合需要广播信息的场景。 6. 安全性 DTLS:CoAP 可以与 DTLS(Datagram Transport Layer Security)结合使用,以提供数据加密和安全性,保护数据在传输过程中的安全。 应用场景 物联网:CoAP 广泛应用于物联网设备的通信,如智能家居、环境监测、工业自动化等。 资源受限设备:适合用于低功耗、低带宽的设备和网络环境。 在go中使用coap echo服务 server: package main import ( "fmt" "log" "github.com/plgd-dev/go-coap/v3" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" "github.com/plgd-dev/go-coap/v3/mux" ) func main() { r := mux....

一些docker和k8s的笔记

常见的项目Dockerfile golang项目 # 构建阶段 FROM golang:1.23 AS builder # 设置工作目录, WORKDIR /app # 复制go.mod和go.sum文件 COPY go.mod go.sum ./ # 设置goproxy RUN go env -w GOPROXY='https://goproxy.io,https://goproxy.cn,direct' # 下载依赖 RUN go mod download # 复制源代码 COPY . . # 构建应用 RUN CGO_ENABLED=0 GOOS=linux go build -o server . # 运行阶段 FROM alpine:latest # 安装ca-certificates以支持HTTPS, RUN apk --no-cache add ca-certificates WORKDIR /root/ # 从构建阶段复制编译好的二进制文件 COPY --from=builder /app/server . # 暴露端口(如果您的应用监听某个端口) EXPOSE 8080 # 运行应用 CMD ["....

MacOS常用软件

聊天和社交 QQ - 80,90的青春。 微信 - 国内TOP1社交软件。 钉钉 - 阿里巴巴出品协同办公软件。 企业微信 - 腾讯出品协同办公软件。 飞书 - 字节跳动出品协同办公软件。 Telegram - 地下社交软件,通信加密。 X(原twitter) - 地下社交软件,了解国内外大事。 XDeck 𝕏桌面客户端 Franz 多合一聊天工具 邮箱工具 Spark 输入法及键盘扩展 AutoSwitchinput 当你在Mac上打开不同的软件的时候,它可以自动帮你切换中文和英文输入法 Input Source Pro,推友开发的一个输入法自动切换工具 Tickeys 键盘打字风格模拟应用, 支持 Cherry轴等多种风格. keycue 快捷键辅助应用, 帮助记忆快捷键. KeyKey macOS 上优雅好用的键盘打字练习。 Karabiner-Elements 键盘映射工具 翻译和外语学习工具 bob - 翻译神器 EasyDict GoldenDict 有道词典 deepl Eudic 新闻及阅读 NetNewsWire rss阅读软件 Reeder 界面优美的RSS订阅应用. 浏览器 Chrome - Google出品,全球最流行的浏览器。 vivaldi 我的偏爱浏览器,前opera团队开发的。 Safari - Apple自己的浏览器,毋庸置疑的好用。 Edge - 微软出品,基于Chromium内核,IE浏览器的替代者。 Firefox - Mozilla出品,早年开发者必备。 Tor - 洋葱浏览器,可浏览AW。 360极速浏览器Pro - 目前Mac上支持Flash的浏览器。 下载及同步工具 Downie4 - 视频下载工具,可以下载YouTube,bilibili等视频网站的视频,并且是满速下载。...

在rust中使用duckdb的一些笔记

基本使用 添加cargo包 在cargo.toml中添加 [dependencies] duckdb = {version = "1"} 示例代码 use duckdb::{params, Connection, Result}; use duckdb::arrow::record_batch::RecordBatch; use duckdb::arrow::util::pretty::print_batches; #[derive(Debug)] struct Person { id: i32, name: String, data: Option<Vec<u8>>, } fn main() -> Result<()> { let conn = Connection::open_in_memory()?; conn.execute_batch( r"CREATE SEQUENCE seq; CREATE TABLE person ( id INTEGER PRIMARY KEY DEFAULT NEXTVAL('seq'), name TEXT NOT NULL, data BLOB ); ")?; let me = Person { id: 0, name: "Steven".to_string(), data: None, }; conn....