用goroutine+channel实现非阻塞通知:Notify函数内启goroutine调用SendToWeCom,失败仅打日志;须定义Notifier接口统一各渠道实现,便于测试与扩展;WebSocket推送需安全注册、检查写错、前端主动重连;beeep桌面通知要注意系统权限、图标路径及尺寸。
用 goroutine + channel 快速搭一个非阻塞通知原型
Go 里最轻量的通知起点不是写 HTTP 接口,而是让发送不卡主流程。直接起 goroutine 调用发送逻辑,配合 channel 做简单解耦,5 分钟就能跑通。
- 别在业务函数里同步调用
SendToWeCom()—— 一旦网络超时,整个请求就卡住 - 用
go func() { ... }()包一层,或更清晰地走chan struct{ Title, Body string }投递消息 - 初版不用做重试:失败就打日志,靠人工补发;加重试反而容易掩盖配置错误(比如 token 写错)
- 注意
http.Client要复用,别每次新建 —— 否则可能触发too many open files
func Notify(title, body string) {
go func() {
err := SendToWeCom(title, body)
if err != nil {
log.Printf("weCom notify failed: %v", err)
}
}()
}
为什么必须先定义 Notifier 接口再写实现
硬编码 EmailSender{} 或直接调 beeep.Notify() 看似快,但第二周就会被测试和渠道切换拖垮。
- 所有发送器必须实现统一接口:
type Notifier interface { Send(title, msg string) error } -
beeep、邮件、企业微信、Webhook 都各自封装成结构体,只管实现Send方法 - 单元测试时传入
fakeNotifier,避免真实发消息;CI 环境也能安全跑通 - 上线后想加钉钉通知?只新增一个
DingTalkNotifier,其他代码零改动
gorilla/websocket 实现用户级实时推送的三个关键动作
WebSocket 不是“连上就完事”,真正落地要稳住连接、找对人、容错掉线。