func (this *Client) Send(data []byte) error { if this.Debug { utils.Printf("Sending data: %s\n", string(data)) } client := this.GetClient() if client == nil { return fmt.Errorf("maybe not connected\n") } n, err := client.Write(data) if err != nil { utils.Println("Send data failed:", err) this.Close() return err } if n != len(data) { utils.Println("Write() has blocked, send: %d, all: %d", n, len(data)) this.Close() return fmt.Errorf("Write() has blocked, send: %d, all: %d", n, len(data)) } return nil }
func (this *Client) GetClient() net.Conn { if this.InternalClient == nil { address := net.JoinHostPort(this.Host, this.Port) conn, err := net.DialTimeout("tcp", address, this.Timeout) if err != nil { utils.Println(err) return nil } this.InternalClient = conn this.BufReader = bufio.NewReader(conn) this.BufWriter = bufio.NewWriter(conn) if this.Debug { utils.Printf("Client connected with gucad server (%s %s %s)\n", this.Host, this.Port, this.Timeout) } return this.InternalClient } return this.InternalClient }
func (this *Client) HandShake(protocol, width, height, dpi string, audio []string, video []string, KWArgs map[string]string) bool { var found_protocol bool for index := range PROTOCOLS { if protocol == PROTOCOLS[index] { found_protocol = true break } } if !found_protocol { utils.Printf("Invalid protocol: %s\n", protocol) return false } // 1. Send "select" instruction utils.Println("Send 'select' instruction") err := this.SendInstruction(inst.NewInstruction("select", protocol)) if err != nil { utils.Println("Send 'select' failed:", err) return false } // 2. Receive "args" instruction instruction := this.ReadInstruction() utils.Printf("Expecting 'args' instruction, received: %s\n", instruction.String()) if instruction == nil { utils.Println("Cannot establish Handshake. Connection Lost!") return false } if instruction.OpCode != "args" { utils.Printf("Cannot establish Handshake. Expected opcode 'args', received '%s' instead.\n", instruction.OpCode) return false } // 3. Respond with size, audio & video support utils.Printf("Send 'size' instruction (%s %s %s)\n", width, height, dpi) size_instruction := inst.NewInstruction("size", width, height, dpi) err = this.SendInstruction(size_instruction) if err != nil { utils.Println("Send 'size' failed:", err) return false } utils.Printf("Send 'audio' instruction (%s)\n", audio) err = this.SendInstruction(inst.NewInstruction("audio", audio...)) if err != nil { utils.Println("Send 'audio' failed:", err) return false } utils.Printf("Send 'video' instruction (%s)\n", video) err = this.SendInstruction(inst.NewInstruction("video", video...)) if err != nil { utils.Println("Send 'video' failed:", err) return false } var connect_args []string for idx := range instruction.Args { arg := strings.Replace(instruction.Args[idx], "-", "_", -1) if v, ok := KWArgs[arg]; ok { connect_args = append(connect_args, v) } else { connect_args = append(connect_args, "") } } // 4. Send connect arguments utils.Printf("Send 'connect' instruction (%s)\n", connect_args) err = this.SendInstruction(inst.NewInstruction("connect", connect_args...)) if err != nil { utils.Println("Send 'connect' failed:", err) return false } return true }
func main() { ret := libvirt.EventRegisterDefaultImpl() utils.Println("EventRegisterDefaultImpl ret:", ret) runtime.GOMAXPROCS(runtime.NumCPU()) defer func() { if err := recover(); err != nil { utils.Println("Server Error: ", err.(string)) } }() // 解析命令行参数 flag.Parse() // 自定义初始化 Init() // 设置guacd客户端连接时的调试信息 client.ClientDebug = Config.ServerDebug // 初始化guacd服务连接池 client.Pool.Init(Config.GuacdServer) utils.Println("Try connect to:", Config.MongoURL) // 初始化MongoDB的连接 timeout := time.Duration(Config.MongoTimeout) * time.Second err := mongo.InitMongoDB(Config.MongoURL, timeout) if err != nil { utils.Println(err) os.Exit(1) } // 启动独立的线程测试MongoDB连接 go mongo.TouchMongoDB(Config.ShowCheckConn) utils.Println("Connect to MongoDB OK") // 捕捉信号并设置回调函数 SignalChan = make(chan os.Signal, 1) signal.Notify(SignalChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE, syscall.SIGALRM, syscall.SIGPIPE) go SignalCallback() // 启动性能调试接口 if Config.ServerProfile == true { go func() { http.ListenAndServe(Config.ProfileAddress, nil) }() } utils.Printf("http profile server Running on %s\n", Config.ProfileAddress) addr_splited := strings.Split(Config.ListenAddress, ":") if len(addr_splited) < 2 { utils.Println("the format of listen address is invalid!") os.Exit(1) } beego.HttpAddr = addr_splited[0] beego.HttpPort, err = strconv.Atoi(addr_splited[1]) beego.SetStaticPath("/static", "./static") beego.Router("/connect", &controllers.MainController{}) beego.Router("/ws", &wscontrollers.WebSocketController{}) beego.Router("/ws/spice", &spicecontrollers.SpiceController{}) beego.Router("/ws/libvirt", &libvirtcontrollers.LibvirtController{}) beego.Router("/api/conn/list", &managercontrollers.ConnectionManagerController{}, "get:ListConnection") beego.Router("/api/conn/create/:conn_type([a-z]+)", &managercontrollers.ConnectionManagerController{}, "post:CreateConnection") beego.Router("/api/conn/update/:conn_type([a-z]+)", &managercontrollers.ConnectionManagerController{}, "put:UpdateConnection") beego.Router("/api/conn/delete", &managercontrollers.ConnectionManagerController{}, "delete:DeleteConnection") beego.Router("/api/libvirt/host", &libvirtcontrollers.HostController{}) beego.Run() }
func (this *SpiceController) Get() { ws, err := upgrader.Upgrade(this.Ctx.ResponseWriter, this.Ctx.Request, nil) if err != nil { utils.Println("websocket upgrade failed:", err) return } defer func() { utils.Println("websocket client disconnected:", ws.RemoteAddr()) ws.Close() }() Type := this.GetString("type") if Type != "spice" { utils.Printf("invalid protocol: %s\n", Type) return } spice_args, err := GetSPICEArgs(this.Ctx) if err != nil { utils.Println("get args for SPICE failed:", err) return } if spice_args == nil { utils.Println("empty args for SPICE") return } hostname := spice_args["hostname"] port := spice_args["port"] spice_conn, err := net.DialTimeout("tcp", hostname+":"+port, 3*time.Second) if err != nil { utils.Println("Can not connect to spice server:", err) return } writer_buf := make([]byte, 4096) go func() { for { n, err := spice_conn.Read(writer_buf) if err != nil { utils.Println("Error read from spice server:", err) return } err = ws.WriteMessage(websocket.BinaryMessage, writer_buf[:n]) if err != nil { utils.Println("websocket write failed:", err) return } } }() // TODO: use ws.NextReader to reuse memory allocation for { _, data, err := ws.ReadMessage() if err != nil { utils.Println("websocket readmessage failed:", err) return } spice_conn.Write(data) } }