package main /* #include #include #include // 函数声明 (必须在使用前声明) const char* add_driver(char* driverName); const char* get_all_device(int rpcPort, int httpPort); // 线程安全的包装函数 const char* safe_get_all_device(int rpcPort, int httpPort) { static char* result = NULL; if (result != NULL) { free(result); result = NULL; } const char* devices = get_all_device(rpcPort, httpPort); if (devices == NULL) { return ""; } result = strdup(devices); return result; } */ import "C" import ( "encoding/json" "fmt" "io" "net" "os" "runtime" "strconv" "strings" "sync" "unsafe" "github.com/osguydch/ccosproc/gateway" "github.com/osguydch/ccosproc/insecure" usersv1 "github.com/osguydch/ccosproc/proto/device/v3" "github.com/osguydch/ccosproc/server" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" ) type CcosProcConf struct { Application string `json:"Application"` SupportSSL string `json:"SupportSSL"` CertFilePath string `json:"CertFilePath"` PortMap [] struct { Type string `json:"Type"` RPCPort string `json:"RPCPort"` HTTPPort string `json:"HTTPPort"` ProcMap [] struct { Name string `json:"Name"` Index string `json:"Index"` } } } var cMutex sync.Mutex func safeGetAllDevice(rpcPort, httpPort int) string { cMutex.Lock() defer cMutex.Unlock() // 锁定当前 goroutine 到 OS 线程 runtime.LockOSThread() defer runtime.UnlockOSThread() // 调用安全的 C 函数 cResult := C.safe_get_all_device(C.int(rpcPort), C.int(httpPort)) return C.GoString(cResult) } func main() { // Adds gRPC internal logs. This is quite verbose, so adjust as desired! if len(os.Args) < 2{ fmt.Println("Usage: please provide driver config fileanme") return } // 加载配置文件 file, err := os.Open("./srvconf.json") if err != nil { fmt.Printf("Failed to open config file: %v\n", err) os.Exit(1) } // 处理每个驱动配置文件 var driverType string for i, v := range os.Args { if i > 0 { cstr := C.CString(v) driverType = C.GoString(C.add_driver(cstr)) C.free(unsafe.Pointer(cstr)) } } //driverType : Detector_CareRay_1800RF_1234 // 解析驱动类型 drivers := strings.Split(driverType, "_") if len(drivers) < 4 { fmt.Printf("Invalid driver type format: %s\n", driverType) os.Exit(1) } var config CcosProcConf decoder := json.NewDecoder(file) if err := decoder.Decode(&config); err != nil { panic(err) } file.Close() var vendor string vendor = drivers[1] + "_" + drivers[2]+ "_" + drivers[3]; fmt.Printf("Load driver: %s\n", vendor) rpcPort := 9000 httpPort := 9001 var wi int for _,v := range config.PortMap { if v.Type == drivers[0] { //找到对应的类型 fmt.Printf("Got Type PortMap config: %s\n", v.Type) rpcPort,_ = strconv.Atoi(v.RPCPort) httpPort,_ = strconv.Atoi(v.HTTPPort) for _,w := range v.ProcMap { if strings.HasPrefix(vendor, w.Name) { //按厂商名匹配 fmt.Printf("Got Vendor PortMap Index config: %s\n", w.Index) wi,_ = strconv.Atoi(w.Index) rpcPort += wi*2 httpPort += wi*2 break } } break } } // 设置日志 log := grpclog.NewLoggerV2(os.Stdout, io.Discard, io.Discard) grpclog.SetLoggerV2(log) // 查找可用端口 addr := "" var lis net.Listener for i:=0; i<10 ;i++{ addr = fmt.Sprintf("localhost:%d", rpcPort) fmt.Printf("try listen %s\n", addr) lis, err = net.Listen("tcp", addr) if err != nil { fmt.Printf("Failed to listen: %s err %v\n", addr, err) rpcPort += 2 httpPort += 2 fmt.Printf("try another port %d\n", rpcPort) } else { break } } // 获取设备信息 fmt.Printf("[DEBUG] Before C.get_all_device call (rpcPort:%d, httpPort:%d)\n", rpcPort, httpPort) devices := safeGetAllDevice(rpcPort, httpPort) fmt.Printf("[DEBUG] After C.get_all_device call, got: %d devices\n", len(devices)) deviceList := strings.Split(devices, ";") fmt.Printf("new Server with %s, found %d devices\n", addr, len(deviceList)) // 创建gRPC服务器 s := grpc.NewServer( // TODO: Replace with your own certificate! grpc.Creds(credentials.NewServerTLSFromCert(&insecure.Cert)), ) usersv1.RegisterDeviceServer(s, server.New(deviceList)) // 启动gRPC服务 // Serve gRPC Server log.Info("Serving gRPC on https://", addr) go func() { log.Fatal(s.Serve(lis)) }() err = gateway.Run("dns:///" + addr, fmt.Sprintf("%d", httpPort), config.SupportSSL) log.Fatalln(err) }