通过websocket 实现与容器的交互
来源:互联网 发布:平板电脑网络转换器 编辑:程序博客网 时间:2024/06/07 08:45
<!doctype html><html> <head> <title>WEB 控制台</title> <style>body, #terminal {position: absolute; height: 100%; width: 100%; margin: 0px;}</style> </head> <input type="hidden" name="t_id" id="t_id" value="<?=$ns?>" /> <input type="hidden" name="s_id" id="s_id" value="<?=$pn?>" /> <input type="hidden" name="c_id" id="c_id" value="<?=$di?>" /> <input type="hidden" name="md5" id="md5" value="<?=$cs?>" /> <input type="hidden" name="wss" id="wss" value="ws://dockerconsole.intra.ffan.com/ws?nodename=<?=$ip?>" /> <body> <div id="terminal"></div> <script src="/dist/js/gotty/hterm.js"></script> <script src="/dist/js/gotty/gotty.js"></script> </body></html>
upstream 10209202202 { server 10.209.202.202:10001;}upstream 1020920237 { server 10.209.202.37:10001;}upstream 10209204167 { server 10.209.204.167:10001;}upstream 10209204199 { server 10.209.204.199:10001;}
# For more information on configuration, see:# * Official English Documentation: http://nginx.org/en/docs/# * Official Russian Documentation: http://nginx.org/ru/docs/user nginx;worker_processes auto;error_log /var/log/nginx/error.log;# pid /run/nginx.pid;events { worker_connections 1024;}http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 11000; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; set $dynamic $arg_nodename; set $args ''; proxy_pass http://$dynamic; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }}
package mainimport ("flag""fmt""os""os/signal""syscall"app "./console")func main() {var address *string = flag.String("Address", "", "server listen address")var port *string = flag.String("Port", "10001", "server listen port")var sessionKey *string = flag.String("SessionKey", "_auth_user_id", "user serssion key")flag.Parse()options := app.DefaultOptionsoptions.Address = *addressoptions.Port = *portoptions.SessionKey = *sessionKeyapp, err := app.New(nil, &options)registerSignals(app)err = app.Run()if err != nil {exit(err, 4)}}func exit(err error, code int) {if err != nil {fmt.Println(err)}os.Exit(code)}func registerSignals(app *app.App) {sigChan := make(chan os.Signal, 1)signal.Notify(sigChan,syscall.SIGINT,syscall.SIGTERM,)go func() {for {s := <-sigChanswitch s {case syscall.SIGINT, syscall.SIGTERM:if app.Exit() {fmt.Println("Send ^C to force exit.")} else {os.Exit(5)}}}}()}
package appimport ("crypto/md5""encoding/hex""encoding/json""log""net/http""os/exec""sync""text/template""github.com/braintree/manners""github.com/gorilla/websocket""github.com/kr/pty""github.com/yudai/umutex")type App struct {command []stringoptions *Optionsupgrader *websocket.UpgradertitleTemplate *template.TemplateonceMutex *umutex.UnblockingMutex}type Options struct {Address string `hcl:"address"`Port string `hcl:"port"`PermitWrite bool `hcl:"permit_write"`IndexFile string `hcl:"index_file"`TitleFormat string `hcl:"title_format"`EnableReconnect bool `hcl:"enable_reconnect"`ReconnectTime int `hcl:"reconnect_time"`PermitArguments bool `hcl:"permit_arguments"`CloseSignal int `hcl:"close_signal"`Preferences HtermPrefernces `hcl:"preferences"`RawPreferences map[string]interface{} `hcl:"preferences"`SessionKey string `hcl:"session_key"`}var Version = "0.0.1"var DefaultOptions = Options{Address: "",Port: "10001",PermitWrite: true,IndexFile: "",TitleFormat: "DTTY Command",EnableReconnect: true,ReconnectTime: 10,CloseSignal: 1, // syscall.SIGHUPPreferences: HtermPrefernces{},SessionKey: "_auth_user_id",}type InitMessage struct {T_id string `json:t_id`S_id string `json:s_id`C_id string `json:c_id`Md5 string `json:md5`}func checkSameOrigin(r *http.Request) bool {return true}func New(command []string, options *Options) (*App, error) {titleTemplate, _ := template.New("title").Parse(options.TitleFormat)return &App{command: command,options: options,upgrader: &websocket.Upgrader{ReadBufferSize: 1024,WriteBufferSize: 1024,CheckOrigin: checkSameOrigin,},titleTemplate: titleTemplate,onceMutex: umutex.New(),}, nil}func (app *App) Run() error {wsHandler := http.HandlerFunc(app.handleWS)siteHandler := wrapHeaders(http.Handler(http.NewServeMux()))wsMux := http.NewServeMux()wsMux.Handle("/", siteHandler)wsMux.Handle("/ws", wsHandler)siteHandler = (http.Handler(wsMux))siteHandler = wrapLogger(siteHandler)s := manners.NewWithServer(&http.Server{Addr: app.options.Address + ":" + app.options.Port,Handler: siteHandler,})log.Printf("Start server on port " + app.options.Port)log.Fatal(s.ListenAndServe())log.Printf("Exiting...")return nil}func (app *App) handleWS(w http.ResponseWriter, r *http.Request) {log.Printf("New client connected: %s", r.RemoteAddr)if r.Method != "GET" {http.Error(w, "Method not allowed", 405)return}conn, err := app.upgrader.Upgrade(w, r, nil)if err != nil {log.Print("Failed to upgrade connection: " + err.Error())return}//defer conn.Close()_, stream, err := conn.ReadMessage()if err != nil {log.Print("Failed to authenticate websocket connection " + err.Error())conn.Close()return}message := string(stream)log.Print("message=", message)var init InitMessageerr = json.Unmarshal(stream, &init)//todo authif init.C_id == "" {log.Print("Parameter is error:" + init.C_id)conn.WriteMessage(websocket.TextMessage, []byte("Parameter is error !"))conn.Close()return}key := init.T_id + "_" + init.S_id + "_" + init.C_id + "_yunpingtai"md5 := md5Func(key)log.Print(key + ":" + md5)if md5 != init.Md5 {log.Print("Auth is not allowed !")conn.WriteMessage(websocket.TextMessage, []byte("Auth is not allowed!"))conn.Close()return}cmd := exec.Command("docker", "exec", "-ti", init.C_id, "/bin/bash")ptyIo, err := pty.Start(cmd)if err != nil {log.Print("Failed to execute command")return}log.Printf("Command is running for client %s with PID %d ", r.RemoteAddr, cmd.Process.Pid)context := &clientContext{app: app,request: r,connection: conn,command: cmd,pty: ptyIo,writeMutex: &sync.Mutex{},}context.goHandleClient()}func (app *App) Exit() (firstCall bool) {manners.Close()return true}func wrapLogger(handler http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {rw := &responseWrapper{w, 200}handler.ServeHTTP(rw, r)log.Printf("%s %d %s %s", r.RemoteAddr, rw.status, r.Method, r.URL.Path)})}func wrapHeaders(handler http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {w.Header().Set("Server", "GoTTY/"+Version)handler.ServeHTTP(w, r)})}func md5Func(str string) string {h := md5.New()h.Write([]byte(str))cipherStr := h.Sum(nil)return hex.EncodeToString(cipherStr)}
阅读全文
0 0
- 通过websocket 实现与容器的交互
- Go语言实现websocket与前端交互
- java WebSocket在Tomcat容器的实现
- 通过WebView实现页面与ANDRIOD客户端的交互
- 通过GWT RPC实现客户端与服务器端的交互
- 通过bindService方法实现Activity与Service的交互
- 通过bind实现activity与service的交互
- 基于websocket的前端与后端之间的数据交互
- html5-websocket基于远程方法调用的数据交互实现
- 通过WebViewJavascriptBridge实现OC与JS交互
- Tomcat 容器与servlet的交互原理
- flex4 flash与容器的信息交互
- Tomcat 容器与servlet的交互原理
- Tomcat 容器与servlet的交互原理
- Tomcat 容器与servlet的交互原理
- Tomcat 容器与servlet的交互原理
- Tomcat 容器与servlet的交互原理
- Tomcat 容器与servlet的交互原理
- 升级Python2.7导致使用pip等命令安装模块失败
- 基于Hadoop分布式集群YARN模式下的TensorFlowOnSpark平台搭建
- windows64系统安装和配置mongodb
- 牙膏大解迷
- cadence设计PCB流程
- 通过websocket 实现与容器的交互
- xshell的快捷键
- Google Guava学习(4)-Guava Range类
- 实验三链栈
- Android 之ArrayAdapter
- [APP开发技巧] 数据库字段Pointer的操作方法
- OpenGL学习笔记——Blending
- C# 中GUID生成格式的四种格式
- 通过cmd想本地maven仓库添加jar