| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- package main
- /*
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- // 函数声明 (必须在使用前声明)
- 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)
- }
|