go ssh websocket 备份

package controllers

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/gorilla/websocket"
    "log"
    "strconv"
    "strings"
    "vmcmdi/ssh"
)

type WebsocketReceive struct {
    Cmd string `json:"cmd"`
}

type WebsocketSend struct {
    Stdout string `json:"stdout"`
    Msg    string `json:"msg"`
    Err    error  `json:"err"`
}

func DeploySocket(ctx *gin.Context) {
    // create websocket connect
    conn := ctx.MustGet("conn").(*websocket.Conn)
    defer func() { _ = conn.Close() }()

    // validate params
    host := ctx.DefaultQuery("host", "")
    port, err := strconv.Atoi(ctx.DefaultQuery("port", "0"))
    if err != nil {
        _ = conn.WriteJSON(WebsocketSend{Stdout: fmt.Sprintf("(port param) string type to int type err: %s", err.Error())})
        return
    }
    username := ctx.DefaultQuery("username", "")
    password := ctx.DefaultQuery("password", "")
    if host == "" || username == "" || port == 0 {
        _ = conn.WriteJSON(WebsocketSend{Stdout: "params: host or username or port cannot empty"})
        return
    }

    inChan := make(chan []byte, 5)
    outputChan := make(chan string)
    exit := make(chan bool, 5)
    defer func() {
        close(inChan)
        close(outputChan)
        close(exit)
    }()

    // create SSH client
    cliConf := new(ssh.ClientConfig)
    if err := cliConf.CreateSshClient(host, int64(port), username, password); err != nil {
        log.Printf("create ssh client err: %+v", err)
        _ = conn.WriteJSON(WebsocketSend{Stdout: fmt.Sprintf("create ssh client err: %s", err.Error())})
        return
    }
    defer func() { _ = cliConf.SshClient.Close() }()

    // create shell session and
    session, err := cliConf.RunShellTerminal(inChan, outputChan)
    defer func() { _ = session.Close() }()
    if err != nil {
        log.Printf("create sessioon or run shell err: %v", err)
        _ = conn.WriteJSON(WebsocketSend{Stdout: fmt.Sprintf("create sessioon or run shell err: %s", err.Error())})
        return
    }

    go func() {
        defer func() {recover()}()
        for {
            _, msg, err := conn.ReadMessage() // first connect, check the socket
            if err != nil {
                if strings.Contains(err.Error(), "websocket: close 1005") {
                    log.Printf("web site active disconnect: %v", err)
                }else if strings.Contains(err.Error(), "use of closed network connection") {
                    log.Printf("backend server active disconnect: %v", err)
                }else {
                    log.Printf("unknown error: %v", err)
                }

                exit <- true
                outputChan <- ""
                break
            }
            if string(msg) == "" {
                continue
            }
            for _, b := range []byte("\n") {
                msg = append(msg, b)
            }
            inChan <- msg
        }
    }()

    //sessionExit := make(chan bool)
    go func() {
        defer func() {recover()}()
        _ = session.Wait()
        exit <- true
        outputChan <- ""
        return
    }()

    for m := range outputChan {
        select {
        case <-exit:
            log.Println("websocket send message loop end")
            return
        default:
            if err := conn.WriteJSON(WebsocketSend{Stdout: m}); err != nil {
                log.Printf("websocket send mesaage err: %s", err.Error())
            }
        }
    }
}

 

posted @ 2020-03-28 00:56  静静别跑  阅读(255)  评论(0编辑  收藏  举报