github.com/zhongdalu/gf@v1.0.0/g/os/gproc/gproc_comm_send.go (about) 1 // Copyright 2018 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 package gproc 8 9 import ( 10 "bytes" 11 "encoding/json" 12 "errors" 13 "fmt" 14 "github.com/zhongdalu/gf/g/net/gtcp" 15 "github.com/zhongdalu/gf/g/os/gfcache" 16 "github.com/zhongdalu/gf/g/util/gconv" 17 "io" 18 "time" 19 ) 20 21 const ( 22 gPROC_COMM_FAILURE_RETRY_COUNT = 3 // 失败重试次数 23 gPROC_COMM_FAILURE_RETRY_TIMEOUT = 1000 // (毫秒)失败重试间隔 24 gPROC_COMM_SEND_TIMEOUT = 5000 // (毫秒)发送超时时间 25 gPROC_COMM_DEAFULT_GRUOP_NAME = "" // 默认分组名称 26 ) 27 28 // 向指定gproc进程发送数据. 29 func Send(pid int, data []byte, group ...string) error { 30 msg := Msg{ 31 SendPid: Pid(), 32 RecvPid: pid, 33 Group: gPROC_COMM_DEAFULT_GRUOP_NAME, 34 Data: data, 35 } 36 if len(group) > 0 { 37 msg.Group = group[0] 38 } 39 msgBytes, err := json.Marshal(msg) 40 if err != nil { 41 return err 42 } 43 var buf []byte 44 var conn *gtcp.PoolConn 45 // 循环获取连接TCP对象 46 for i := gPROC_COMM_FAILURE_RETRY_COUNT; i > 0; i-- { 47 if conn, err = getConnByPid(pid); err == nil { 48 break 49 } 50 time.Sleep(gPROC_COMM_FAILURE_RETRY_TIMEOUT * time.Millisecond) 51 } 52 if conn == nil { 53 return err 54 } 55 defer conn.Close() 56 // 执行数据发送 57 buf, err = conn.SendRecvPkgWithTimeout(msgBytes, gPROC_COMM_SEND_TIMEOUT*time.Millisecond) 58 if len(buf) > 0 { 59 if !bytes.EqualFold(buf, []byte("ok")) { 60 err = errors.New(string(buf)) 61 } 62 } 63 // EOF不算异常错误 64 if err == io.EOF { 65 err = nil 66 } 67 return err 68 } 69 70 // 获取指定进程的TCP通信对象 71 func getConnByPid(pid int) (*gtcp.PoolConn, error) { 72 port := getPortByPid(pid) 73 if port > 0 { 74 if conn, err := gtcp.NewPoolConn(fmt.Sprintf("127.0.0.1:%d", port)); err == nil { 75 return conn, nil 76 } else { 77 return nil, err 78 } 79 } 80 return nil, errors.New(fmt.Sprintf("could not find port for pid: %d", pid)) 81 } 82 83 // 获取指定进程监听的端口号 84 func getPortByPid(pid int) int { 85 path := getCommFilePath(pid) 86 content := gfcache.GetContents(path) 87 return gconv.Int(content) 88 }