main.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package main
  2. /*
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. // 函数声明 (必须在使用前声明)
  7. const char* add_driver(char* driverName);
  8. const char* get_all_device(int rpcPort, int httpPort);
  9. // 线程安全的包装函数
  10. const char* safe_get_all_device(int rpcPort, int httpPort) {
  11. static char* result = NULL;
  12. if (result != NULL) {
  13. free(result);
  14. result = NULL;
  15. }
  16. const char* devices = get_all_device(rpcPort, httpPort);
  17. if (devices == NULL) {
  18. return "";
  19. }
  20. result = strdup(devices);
  21. return result;
  22. }
  23. */
  24. import "C"
  25. import (
  26. "encoding/json"
  27. "fmt"
  28. "io"
  29. "net"
  30. "os"
  31. "runtime"
  32. "strconv"
  33. "strings"
  34. "sync"
  35. "unsafe"
  36. "github.com/osguydch/ccosproc/gateway"
  37. "github.com/osguydch/ccosproc/insecure"
  38. usersv1 "github.com/osguydch/ccosproc/proto/device/v3"
  39. "github.com/osguydch/ccosproc/server"
  40. "google.golang.org/grpc"
  41. "google.golang.org/grpc/credentials"
  42. "google.golang.org/grpc/grpclog"
  43. )
  44. type CcosProcConf struct {
  45. Application string `json:"Application"`
  46. SupportSSL string `json:"SupportSSL"`
  47. CertFilePath string `json:"CertFilePath"`
  48. PortMap [] struct {
  49. Type string `json:"Type"`
  50. RPCPort string `json:"RPCPort"`
  51. HTTPPort string `json:"HTTPPort"`
  52. ProcMap [] struct {
  53. Name string `json:"Name"`
  54. Index string `json:"Index"`
  55. }
  56. }
  57. }
  58. var cMutex sync.Mutex
  59. func safeGetAllDevice(rpcPort, httpPort int) string {
  60. cMutex.Lock()
  61. defer cMutex.Unlock()
  62. // 锁定当前 goroutine 到 OS 线程
  63. runtime.LockOSThread()
  64. defer runtime.UnlockOSThread()
  65. // 调用安全的 C 函数
  66. cResult := C.safe_get_all_device(C.int(rpcPort), C.int(httpPort))
  67. return C.GoString(cResult)
  68. }
  69. func main() {
  70. // Adds gRPC internal logs. This is quite verbose, so adjust as desired!
  71. if len(os.Args) < 2{
  72. fmt.Println("Usage: please provide driver config fileanme")
  73. return
  74. }
  75. // 加载配置文件
  76. file, err := os.Open("./srvconf.json")
  77. if err != nil {
  78. fmt.Printf("Failed to open config file: %v\n", err)
  79. os.Exit(1)
  80. }
  81. // 处理每个驱动配置文件
  82. var driverType string
  83. for i, v := range os.Args {
  84. if i > 0 {
  85. cstr := C.CString(v)
  86. driverType = C.GoString(C.add_driver(cstr))
  87. C.free(unsafe.Pointer(cstr))
  88. }
  89. }
  90. //driverType : Detector_CareRay_1800RF_1234
  91. // 解析驱动类型
  92. drivers := strings.Split(driverType, "_")
  93. if len(drivers) < 4 {
  94. fmt.Printf("Invalid driver type format: %s\n", driverType)
  95. os.Exit(1)
  96. }
  97. var config CcosProcConf
  98. decoder := json.NewDecoder(file)
  99. if err := decoder.Decode(&config); err != nil {
  100. panic(err)
  101. }
  102. file.Close()
  103. var vendor string
  104. vendor = drivers[1] + "_" + drivers[2]+ "_" + drivers[3];
  105. fmt.Printf("Load driver: %s\n", vendor)
  106. rpcPort := 9000
  107. httpPort := 9001
  108. var wi int
  109. for _,v := range config.PortMap {
  110. if v.Type == drivers[0] {
  111. //找到对应的类型
  112. fmt.Printf("Got Type PortMap config: %s\n", v.Type)
  113. rpcPort,_ = strconv.Atoi(v.RPCPort)
  114. httpPort,_ = strconv.Atoi(v.HTTPPort)
  115. for _,w := range v.ProcMap {
  116. if strings.HasPrefix(vendor, w.Name) {
  117. //按厂商名匹配
  118. fmt.Printf("Got Vendor PortMap Index config: %s\n", w.Index)
  119. wi,_ = strconv.Atoi(w.Index)
  120. rpcPort += wi*2
  121. httpPort += wi*2
  122. break
  123. }
  124. }
  125. break
  126. }
  127. }
  128. // 设置日志
  129. log := grpclog.NewLoggerV2(os.Stdout, io.Discard, io.Discard)
  130. grpclog.SetLoggerV2(log)
  131. // 查找可用端口
  132. addr := ""
  133. var lis net.Listener
  134. for i:=0; i<10 ;i++{
  135. addr = fmt.Sprintf("localhost:%d", rpcPort)
  136. fmt.Printf("try listen %s\n", addr)
  137. lis, err = net.Listen("tcp", addr)
  138. if err != nil {
  139. fmt.Printf("Failed to listen: %s err %v\n", addr, err)
  140. rpcPort += 2
  141. httpPort += 2
  142. fmt.Printf("try another port %d\n", rpcPort)
  143. } else {
  144. break
  145. }
  146. }
  147. // 获取设备信息
  148. fmt.Printf("[DEBUG] Before C.get_all_device call (rpcPort:%d, httpPort:%d)\n", rpcPort, httpPort)
  149. devices := safeGetAllDevice(rpcPort, httpPort)
  150. fmt.Printf("[DEBUG] After C.get_all_device call, got: %d devices\n", len(devices))
  151. deviceList := strings.Split(devices, ";")
  152. fmt.Printf("new Server with %s, found %d devices\n", addr, len(deviceList))
  153. // 创建gRPC服务器
  154. s := grpc.NewServer(
  155. // TODO: Replace with your own certificate!
  156. grpc.Creds(credentials.NewServerTLSFromCert(&insecure.Cert)),
  157. )
  158. usersv1.RegisterDeviceServer(s, server.New(deviceList))
  159. // 启动gRPC服务
  160. // Serve gRPC Server
  161. log.Info("Serving gRPC on https://", addr)
  162. go func() {
  163. log.Fatal(s.Serve(lis))
  164. }()
  165. err = gateway.Run("dns:///" + addr, fmt.Sprintf("%d", httpPort), config.SupportSSL)
  166. log.Fatalln(err)
  167. }