• go实现jupyter代码的运行


    a.go文件

    package ws
    
    import (
        "fallout/common"
        "fallout/sshed"
        "fmt"
        "github.com/gorilla/websocket"
        "log"
        "net/http"
        "strings"
    )
    
    
    // ConnWebsocket 连接远端websocket
    func ConnWebsocket(kernelsId string, authorization string,cookie string, port string) *websocket.Conn {
        var ip = common.LoadConfig().Learning.Host
        // ConnWebsocket var addr = flag.String("addr", "127.0.0.1:8887", "http service address")
        //var addr = flag.String("addr", "192.168.0.121:3839", "http service address")
        //var addr = flag.String("addr", ip+":"+port, "http service address")
        //fmt.Println(addr)
        fmt.Println("确认id是否正确",kernelsId)
        //u := url.URL{Scheme: "ws", Host: *addr, Path: "/api/kernels/"+kernelsId+"/channels"}
        //fmt.Println(u)
        var dialer *websocket.Dialer
        header := http.Header{
            ////"Authorization": []string{"Token 49bb7f981a7cf2647fb22e6095bae531c80a443e69aa6068\n"},
            //"Authorization": []string{authorization},
            ////"cookie":[]string{"_xsrf=2|5c5e01d3|93bd93516399f1e743638595777ba036|1648890405; username-192-168-0-121-3839=\"2|1:0|10:1650448749|27:username-192-168-0-121-3839|44:NWQ2M2Q2NTdhNDFiNDM4YzgxYTdiMjFkNjA3ZDRiNmY=|8ecf4ce9d9e4804b73c75d761f0ef2124e6ddf373f68699004d6ed2204c5d813\""},
            //"cookie":[]string{cookie},
            //"X-XSRFToken":[]string{"123"},
            "Authorization": []string{common.LoadConfig().Learning.Authorization},
            "cookie":[]string{common.LoadConfig().Learning.Cookie},
            "X-XSRFToken":[]string{common.LoadConfig().Learning.Xsrftoken},
        }
        //conn, _, err := dialer.Dial(u.String()+"?session_id=6a6af4cc0bde4b50ba4b9518336514ca", header)
        //conn, _, err := dialer.Dial(u.String(), header)
        conn, _, err := dialer.Dial("ws://"+ip+":"+port+"/api/kernels/"+kernelsId+"/channels", header)
        //conn, _, err := dialer.Dial("ws://192.168.0.121:3839/api/kernels/fcb7ef0f-55f6-401e-9818-d907b0337149/channels", header)
        if err != nil {
            log.Println(err)
            return nil
        }else{
            log.Println("链接成功!")
        }
        return conn
    }
    
    // ReceiveNews 接收数据
    func ReceiveNews(conn *websocket.Conn, path string,username string,kernelId string) {
      //读取某个文件的内容
        //fmt.Println(aa["cells"])
        aa :=common.ReadFileCon(path)
        connMyWebsocket :=ConnMyWebsocket(username)
        var status =""
    
        cells := aa["cells"].([]interface{})
        for key,value :=range cells{
            cellValue := value.(map[string]interface{})
            if cellValue["cell_type"]=="code" {
                for {
                    _, message, err := conn.ReadMessage()
                    log.Printf("received: %s\n", message)
                    if err != nil {
                        //fmt.Println("read:", err)
                        log.Println("read:", err)
                        return
                    }
                    con,_:= common.JsonToMap(string(message))
                    fmt.Println("1111111111111111111111111111111111111122222222222222")
                    fmt.Println(con["msg_type"])
                    content:=con["content"].(map[string]interface{})
                    //代表程序开始运行
                    if con["msg_type"]=="execute_input"{
                        executionCount, ok:=content["execution_count"]
                        if ok {
                            cells[key].(map[string]interface{})["executionCount"] = executionCount
                        }
                    }
                    //代表程序运行结束
                    if con["msg_type"]=="execute_reply"{
                        stus := content["status"]
                        if stus=="ok"{  //代表单元格程序正常执行成功
                            fmt.Println(stus)
                            break
                        }else if stus!="error" {  //如果不等于ok得时候,退出双层循环 status="aborted"
                            status = stus.(string)
                            break
                        }else{
                            fmt.Println("content error")
                            data := map[string] interface{}{"ename": content["ename"], "evalue": content["evalue"],
                                "output_type": con["status"], "traceback":content["traceback"]}
                            //append追加之后还需要接收
                            outputs :=append(cells[key].(map[string]interface{})["outputs"].([]interface{}),data)
                            cells[key].(map[string]interface{})["outputs"]=outputs
                            break
                        }
                    }
                    //当内核重启时,结束运行
                    if con["msg_type"]=="status"{  //restarting 退出双层循环
                        //fmt.Println(con["content"]) //["execution_count"]
                        ////execution_count := con["content"]["execution_count"]
                        executionState,_:=content["execution_state"]
                        if executionState == "restarting"{
                            status =  content["execution_state"].(string)
                            info:=map[string]interface{}{"username":username, "message":"内核重启!"}
                            SendNewsClient(connMyWebsocket, common.MapToJson(info))
                            break
                        }
                    }
                    if con["msg_type"] == "error"{
                        fmt.Println( con["msg_type"])
                        data := map[string] interface{}{"ename": content["ename"], "evalue": content["evalue"],
                            "output_type": con["msg_type"], "traceback":content["traceback"]}
                        //append追加之后还需要接收
                        outputs :=append(cells[key].(map[string]interface{})["outputs"].([]interface{}),data)
                        cells[key].(map[string]interface{})["outputs"]=outputs
                        break
                    }
                    //# 返回程序得运行结果
                    if con["msg_type"] == "stream"{//strip().strip("\b").strip("\r").strip()
                        obj :=map[string] interface{}{"name":content["name"],"output_type": con["msg_type"],
                            "text": [1]string{strings.Trim(content["text"].(string),"\b")}}
                        //append追加之后还需要接收
                        outputs :=append(cells[key].(map[string]interface{})["outputs"].([]interface {}),obj)
                        cells[key].(map[string]interface{})["outputs"]=outputs
                    }
                    //返回程序得运行结果 图片之类的
                    if con["msg_type"] == "display_data"{
                        data :=map[string]interface{}{"metadata": con["metadata"],
                            "data": map[string] interface{}{"text/plain":[1]string{content["data"].(map[string]interface{})["text/plain"].(string)},
                                "image/png": content["data"].(map[string]interface{})["image/png"].(string)}, "output_type": con["msg_type"]}
    
                        //append追加之后还需要接收
                        cells[key].(map[string]interface{})["outputs"]=append(cells[key].(map[string]interface{})["outputs"].([]interface {}),data)
                    }
                    //# print(con["content"]["text"])
                    //fmt.Printf("received: %s\n", message)
                    //将消息转发给前台
                    //SendNewsClient(connMyWebsocket, string(message))
                    //log.Println(reflect.TypeOf(message))
    
                }
                if status!="" {
                    break
                }
            }
    
        }
        //关闭连接
        conn.Close()
        //程序运行结束之后,关闭对应的内核
        closeRs := sshed.CloseSingleKernel(kernelId)
        fmt.Println(closeRs)
        //将运行结果写入对应的运行结果文件中
        rs:= common.WriteFileCon(path,common.MapToJson(aa))
        fmt.Println(rs)
        path=strings.Replace(path,".","",1)
        path=strings.Replace(path,".ipynb","(运行).ipynb",1)
        info:=map[string]interface{}{"username":username,"path":path, "message":"已经运行结束!"}
       
    }
    
    // TimeWriter 推送数据
    func TimeWriter(conn *websocket.Conn,sendData string) {
        //fmt.Println("//////////////////////////////")
        //fmt.Println(sendData)
        //time.Sleep(time.Second * 5)
        err:=conn.WriteMessage(
            websocket.TextMessage,
            []byte(sendData),
        )
        if err != nil {
            log.Println("write:", err)
            return
        }
        //for {
        //    //time.Sleep(time.Second * 5)
        //    //conn.WriteMessage(websocket.TextMessage, []byte(time.Now().Format("2006-01-02 15:04:05")))
        //    encodeInfo,_ :=json.Marshal(&msg)
        //    conn.WriteMessage(websocket.TextMessage, encodeInfo)
        //}
    }

    main.go文件

    package main

    import (
    "bytes"
    "encoding/base64"
    "encoding/json"
    "fallout/common"
    "fallout/sshed"
    "fallout/ws"
    "fmt"
    "github.com/gin-gonic/gin"
    uuid "github.com/satori/go.uuid"
    "io/ioutil"
    "log"
    "net/http"
    "os"
    "os/exec"
    "path"
    "reflect"
    "strconv"
    "strings"
    "time"
    )

    func main() {
    r := gin.Default()
    //加载模版文件
    r.Use(static.Serve("/", static.LocalFile("templates/*.html", true)))

    // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
    //r.MaxMultipartMemory = 8 << 20 // 8 MiB

    r.GET("/runCode",RunCodeHandler)
    r.GET("/", func(c *gin.Context) {
    c.HTML(http.StatusOK, "index.html", gin.H{
    "title": "Main website",
    })
    })

    err :=r.Run(":1234")
    if err!=nil{
    fmt.Println("error")
    }
    }

    func RunCodeHandler(c *gin.Context){ username := c.Query("username") port :=c.Query("port") // 教学端用户使用的端接口号是3839,科研端的是端口号加1 fileName :=c.Query("filename") if username!="" && port!="" &&fileName!="" { //这两个参数必传 authorization :=common.LoadConfig().Learning.Authorization cookie:=common.LoadConfig().Learning.Cookie var base = "http://"+common.LoadConfig().Minio.Host+":"+port var url = base + "/api/kernels" fmt.Println(base) body,_ :=common.GetThirdData("POST",url, "") resId,err :=common.JsonToMap(body) if message,ok:=resId["message"];ok { c.JSON(http.StatusOK, gin.H{"status": 3, "message": message}) }else{ if err!=nil{ c.JSON(http.StatusOK, gin.H{"status": 2, "message":err}) }else{ _id:=resId["id"].(string) fmt.Println("kernelsID",_id) //fmt.Println(reflect.TypeOf(_id)) //var notebookPath ="/home/jupyter/tf2/入门神经网络.ipynb" var notebookPath =common.LoadConfig().Learning.Targetpath+fileName //var base = "http://192.168.0.121:8089" var conUrl = base + "/api/contents"+ notebookPath fmt.Println("1233555") fmt.Println(conUrl) body1,_:=common.GetThirdData("GET",conUrl, "") aa, er :=common.JsonToMap(body1) //fmt.Println(er) if er!=nil{ fmt.Println(reflect.TypeOf(er)) c.JSON(http.StatusOK, gin.H{"status": 2, "message":er}) }else{ cells1,ok1 :=aa["content"] if ok1 { //2. 启动对应文件接收运行结果消息 conn := ws.ConnWebsocket(_id, authorization,cookie, port) if conn != nil { localpath :="./dataset/algorithm/"+fileName go ws.ReceiveNews(conn, localpath,username,_id) //3. 获取运行文件的代码并进行解析 cells :=cells1.(map[string]interface{})["cells"].([]interface{}) //将数据转为数组对象类型 ul:=strings.Replace(uuid.NewV4().String(), "-", "", -1) fmt.Println(ul) for _, value := range cells { //go生成uuid //ul:=strings.Replace(uuid.NewV4().String(), "-", "", -1) //fmt.Println(ul) //根据当前时间,将本地时间转为指定格式 currTime :=time.Now().UTC().Format("2006-01-02 15:04:05") local, _ := time.LoadLocation("Local") rfc, _ := time.ParseInLocation("2006-01-02 15:04:05", currTime, local) hdr :=common.Hdr{ MsgId: ul, Username:username, Session: ul, Data:rfc, MsgType:"execute_request", Version:"5.0", } cellValue := value.(map[string]interface{}) //将数据转为map类型,其中"."后面的括号里面的代表强转 if cellValue["cell_type"]=="code"{ simpleCode := cellValue["source"] content :=common.Content{ Code: simpleCode.(string), Silent: false, } msg:=common.Msg{ Header:&hdr, ParentHeader:&hdr, Metadata: make(map[string]interface{}), Content:&content, } encodeInfo,_ :=json.Marshal(msg) ws.TimeWriter(conn, string(encodeInfo)) } //break } //conn.Close() //返回json结果 c.JSON(http.StatusOK, gin.H{"status": 1, "message":"程序正在运行中。。。。。。"}) }else{ c.JSON(http.StatusOK, gin.H{"status": 3, "message":"运行出现异常!"}) } }else{ c.JSON(http.StatusOK, gin.H{"status": 2, "message":aa["message"]}) } } } } }else{ c.JSON(http.StatusOK, gin.H{"status": -1, "message":"参数传递有误!"}) } }
  • 相关阅读:
    如何通过setTimeout理解JS运行机制详解
    css3系列之伪类选择器
    css3系列之属性选择器
    css3系列之伪元素选择器
    css3系列之兄弟选择器
    作为了解系列之 预处理器 和 后处理器
    网络系列之跨域
    网络系列之 cookie增删改查(封装)
    网络系列之 jsonp 百度联想词
    网络系列之 什么是ajax 封装ajax
  • 原文地址:https://www.cnblogs.com/lxz123/p/16352634.html
Copyright © 2020-2023  润新知