● 通过命令行启动启动服务
// 第一个命令行参数指定监听端口 $ ./gocron 4567
GoCron listening on 4567
● 创建新的任务
// 每 5 秒钟执行一次 date -R
// 子进程的输出直接用服务进程的标准输出即可
// 服务返回 HTTP 200:
{ ”ok”: true, ”id”: ”print-time”}
// 任务以存在,服务返回 HTTP 409:
{ ”ok”: false, ”error”: ”The task print-time already exists.”}// 用 JSON POST 去创建任务 curl -X POST localhost:4567 -d '
{
"id": "print-time", "cmd": "date", "args": ["-R"], "interval": 5000
}
'
// 每 5 秒钟执行一次 date -R
// 子进程的输出直接用服务进程的标准输出即可 // 服务返回 HTTP 200:
{ "ok": true, "id": "print-time"}
// 任务以存在,服务返回 HTTP 409:
{ "ok": false, "error": "The task print-time already exists."}
● 终止定时任务
// 服务返回, HTTP 200:
{ ”ok”: true, ”id”: ”print-time”}
// 没有该任务的话, HTTP 404:
{ ”ok”: false, ”error”: ”The task print-time is not found.”}curl -X DELETE localhost:4567 -d '
{
"id": "print-time",
} '
// 服务返回, HTTP 200:
{ "ok": true, "id": "print-time"}
// 没有该任务的话, HTTP 404:
{ "ok": false, "error": "The task print-time is not found."}
下面是答案——————
package main
import (
"bufio"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"time"
//"runtime/debug"
)
var Debug = true
var tickMaps = make(map[string]*time.Timer)
type BodyJson struct {
Id string
Cmd string
Args []string
Interval time.Duration
}
type DBodyJson struct {
Id string
}
func newTimer(id string, cmd string, args []string, interval time.Duration) {
tickMaps[id] = time.NewTimer(time.Millisecond * interval)
for {
select {
case <-tickMaps[id].C:
tCmd := exec.Command(cmd, args...)
stdout, err := tCmd.StdoutPipe()
if err != nil {
fmt.Println(err)
break
}
tCmd.Start()
reader := bufio.NewReader(stdout)
for {
line, err2 := reader.ReadString('\n')
if err2 != nil || io.EOF == err2 {
break
}
fmt.Println(line)
}
tCmd.Wait()
fmt.Println(8888)
tickMaps[id].Reset(time.Millisecond * interval)
}
}
}
func HelloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.Method)
if r.Method == "POST" {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Printf("read body err, %v\n", err)
return
}
var tbody BodyJson
if err = json.Unmarshal(body, &tbody); err != nil {
fmt.Printf("Unmarshal err, %v\n", err)
return
}
id := tbody.Id
cmd := tbody.Cmd
args := tbody.Args
interval := tbody.Interval
if tickMaps[id] == nil {
go newTimer(id, cmd, args, interval)
data := map[string]interface{}{"id": id, "ok": true}
d, _ := json.Marshal(data)
w.Header().Set("Content-Type", "text/json")
w.Write([]byte(d))
} else {
data := map[string]interface{}{"error": "this " + id + "already exists.", "ok": false}
d, _ := json.Marshal(data)
w.Header().Set("Content-Type", "text/json")
w.Write([]byte(d))
}
} else if r.Method == "DELETE" {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Printf("read body err, %v\n", err)
return
}
var tbody DBodyJson
if err = json.Unmarshal(body, &tbody); err != nil {
fmt.Printf("Unmarshal err, %v\n", err)
return
}
id := tbody.Id
if tickMaps[id] != nil && tickMaps[id].Stop() {
data := map[string]interface{}{"id": id, "ok": true}
d, _ := json.Marshal(data)
w.Header().Set("Content-Type", "text/json")
w.Write([]byte(d))
} else {
data := map[string]interface{}{"error": "this " + id + "not found", "ok": false}
d, _ := json.Marshal(data)
w.Header().Set("Content-Type", "text/json")
w.Write([]byte(d))
}
}
}
func main() {
//debug.PrintStack()
if len(os.Args) != 2 {
fmt.Println("no port param")
return
}
port := os.Args[1]
http.HandleFunc("/", HelloWorld)
fmt.Println("GoCron listening on " + port)
err := http.ListenAndServe(":"+port, nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
return
}
}