1 主进程为nodejs 进程,为了给nodejs 进程提供计算心率hrv服务,制作该微服务进程,占用一个端口
2 利用go服务携程进行概率计算服务,不占用nodejs主进程
a 从传感器传入数据,接收到数据以后存储
b 需要计算的时候调用算法服务
hrv 5 min RR 间期 平均值标准差 sdann
24h 正常的RR间期总体标准差 sdnn
24h 每5分钟时段 标准差的平均值 sdnn index
两个相邻RR间期 差值的均方根RMSSD
24h 相邻两个正常RR 间期差值 大于50ms 的个数百分比pnn50
主要计算公式如下
写好mode包模式,go.mode 内容如下
module hrv
go 1.15
require github.com/garyburd/redigo v1.6.3
如下,心率数据和时间,姓名
type Data struct {
Heart int
Time int
Name string
}
type Cmd struct {
Type int
Data []Data
}
携程函数示例
func calculate1(cmd *Cmd, w http.ResponseWriter) {
//in1 := []float32{71, 72, 69, 70, 65, 74}
size := len(cmd.Data)
var in []float32 = make([]float32, size)
for i, v := range cmd.Data {
in[i] = (float32)(v.Heart)
}
//标准差函数在sdnn包里面
ret := sdnn.Get_Stddev(in)
fmt.Fprintf(w, "%f", ret)
//
}
启动函数的时候这样写
go calculate(cmd,w)
这样没接收到一个任务以后,都会启动携程处理,然后返回结果
package main
import (
"encoding/json"
"fmt"
"hrv/sdnn"
"html"
"io/ioutil"
"log"
"net/http"
)
type Data struct {
Heart int
Time int
Name string
}
type Cmd struct {
Type int
Data []Data
}
// 创建一个错误处理函数,避免过多的 if err != nil{} 出现
func dropErr(e error) {
if e != nil {
panic(e)
}
}
func calculate1(cmd *Cmd, w http.ResponseWriter) {
//in1 := []float32{71, 72, 69, 70, 65, 74}
size := len(cmd.Data)
var in []float32 = make([]float32, size)
for i, v := range cmd.Data {
in[i] = (float32)(v.Heart)
}
ret := sdnn.Get_Stddev(in)
fmt.Fprintf(w, "%f", ret)
//
}
func main() {
runtime.GOMAXPROCS(4)
http.HandleFunc("/hrv", func(w http.ResponseWriter, r *http.Request) {
fmt.Println(html.EscapeString(r.URL.Path))
if r.Method == "POST" {
b, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Println("Read failed:", err)
}
defer r.Body.Close()
cmd := &Cmd{}
err = json.Unmarshal(b, cmd)
if err != nil {
log.Println("json format error:", err)
}
//携程处理
go calculate1(cmd, w)
log.Println("cmd:", string(b))
log.Println("cmd:", cmd.Data[0])
//w.ResponseWriter("1")
} else {
log.Println("not support")
w.WriteHeader(405)
return
}
})
fmt.Println("server lister at 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
为了充分利用多核,我们可以设定并发携程处理器个数
runtime.GOMAXPROCS(4)
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
)
type Data struct {
Heart int
Time int
Name string
}
type Cmd struct {
Type int
Data []Data
}
func main() {
str := `{"Type":1,"Data":[{"Heart":78,"Time":678,"Name":"qianbo"},
{"Heart":75,"Time":679,"Name":"guanzhi"},
{"Heart":69,"Time":679,"Name":"guanzhi"},
{"Heart":72,"Time":679,"Name":"guanzhi"},
{"Heart":73,"Time":679,"Name":"guanzhi"},
{"Heart":70,"Time":679,"Name":"guanzhi"}
]}`
//var arr [2]Data
//json.Unmarshal([]byte(str), &s)
// data := make(map[string]interface{})
// data["Name"] = "qianbo"
// data["Heart"] = 67
// data["Time"] = 778
// D := make(map[string]interface{})
// D["Type"] = 1
// D["Data"] = data
// bytesData, err := json.Marshal(D)
// if err != nil {
// fmt.Println(err.Error())
// return
// }
// reader := bytes.NewReader(bytesData)
//request, err := http.NewRequest("POST", url, reader)
url := "http://127.0.0.1:8080/hrv"
var jsonStr = []byte(str)
request, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
if err != nil {
fmt.Println(err.Error())
return
}
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
client := http.Client{}
resp, err := client.Do(request)
if err != nil {
fmt.Println(err.Error())
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(body))
}
运行服务器
go run main.go