《golang日记》关于gio的学习二

我一开始一直在研究单窗口的布局规范和方式,后面我慢慢意识到了一件事情,多窗口怎么互相关联呢,任务之间的数据该怎么传输呢,于是乎我在四月份新发表的multiple windows的example找到了答案。
官方是通过用ctx(一个很让人头疼的东西,简单的说就是上下文的联系)来进行信息传导的,之前报了毛大的课学习架构的时候,一直不明白上下文到底什么意思,结果在研究gio的时候慢慢理解了它的作用。
这次我通过multiple windows写出了一个后端简洁监控系统,我其实很早就完成了,但是我是拿来当作毕业设计的,所以最近才决定把代码发出来,里面有一块地方我不算展示,也就是cardtoken那块的运算代码,那是我之前写某个网站js逆向出来的代码。其实还是有一点值得大家注意,就还是变量作用域的问题,这玩意真的是有点恶心的。

main.go

package main

import (
	"context"
	"gioui.org/app"
	"gioui.org/font/gofont"
	"gioui.org/io/system"
	"gioui.org/layout"
	"gioui.org/op"
	"gioui.org/unit"
	"gioui.org/widget/material"
	"os"
	"os/signal"
	"sync"
)

func main() {

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	go func() {
		a := NewApplication(ctx)
		login_in := NewLogin()
		a.NewWindow("Login_In", login_in, app.Size(unit.Dp(400),unit.Dp(200)))
		a.Wait()
		select {
		case <-login_in.Check:
			grpc_info := NewGrpc()
			go Open_Server(grpc_info)
			a.NewWindow("Monitoring_System", grpc_info)
		}
		a.Wait()
		os.Exit(0)
	}()

	app.Main()
}


type Application struct {

	Context context.Context

	Shutdown func()

	active sync.WaitGroup
}

func NewApplication(ctx context.Context) *Application {
	ctx, cancel := context.WithCancel(ctx)
	return &Application{
		Context:  ctx,
		Shutdown: cancel,
	}
}


func (a *Application) Wait() {
	a.active.Wait()
}


func (a *Application) NewWindow(title string, view View, opts ...app.Option) {
	opts = append(opts, app.Title(title))
	w := &Window{
		App:    a,
		Window: app.NewWindow(opts...),
	}
	a.active.Add(1)
	go func() {
		defer a.active.Done()
		view.Run(w)
	}()
}


type Window struct {
	App *Application
	*app.Window
}


type View interface {

	Run(w *Window) error
}


type WidgetView func(gtx layout.Context, th *material.Theme) layout.Dimensions


func (view WidgetView) Run(w *Window) error {
	var ops op.Ops

	th := material.NewTheme(gofont.Collection())

	applicationClose := w.App.Context.Done()
	for {
		select {
		case <-applicationClose:
			return nil
		case e := <-w.Events():
			switch e := e.(type) {
			case system.DestroyEvent:
				return e.Err
			case system.FrameEvent:
				gtx := layout.NewContext(&ops, e)
				view(gtx, th)
				e.Frame(gtx.Ops)
			}
		}
	}
}

monitoring,go

package main

import (
	"fmt"
	"gioui.org/font/gofont"
	"gioui.org/io/system"
	"gioui.org/layout"
	"gioui.org/op"
	"gioui.org/widget"
	"gioui.org/widget/material"
)

type Monitoring_Info struct {
	list  widget.List
	addLine chan string
	lines   []string
}


func NewGrpc() *Monitoring_Info {
	return &Monitoring_Info{
		addLine: make(chan string, 100),
		list:    widget.List{List: layout.List{Axis: layout.Vertical}},
	}
}

func (monitor *Monitoring_Info)Run(w *Window)  error{
	th := material.NewTheme(gofont.Collection())
	var ops op.Ops

	applicationClose := w.App.Context.Done()
	for {
		select {
		case <-applicationClose:
			return nil
		case line := <-monitor.addLine:
			monitor.lines = append(monitor.lines, line)
			w.Invalidate()
		case e := <-w.Events():
			switch e := e.(type) {
			case system.DestroyEvent:
				return e.Err
			case system.FrameEvent:
				gtx := layout.NewContext(&ops, e)
				monitor.Layout(gtx, th)
				e.Frame(gtx.Ops)
			}
		}
	}

}

func (monitor *Monitoring_Info) Printf(format string, args ...interface{}) {
	s := fmt.Sprintf(format, args...)

	select {
	case monitor.addLine <- s:
	default:
	}
}


func (monitor Monitoring_Info)Layout(gtx layout.Context, th *material.Theme){


	layout.Flex{Axis: layout.Vertical}.Layout(gtx,
		layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
			return material.List(th, &monitor.list).Layout(gtx, len(monitor.lines), func(gtx layout.Context, i int) layout.Dimensions {
				return material.Body1(th, monitor.lines[i]).Layout(gtx)
			})
		}),
	)

}

login_windows.go

package main

import (
	"gioui.org/app"
	"gioui.org/font/gofont"
	"gioui.org/io/system"
	"gioui.org/layout"
	"gioui.org/op"
	"gioui.org/unit"
	"gioui.org/widget"
	"gioui.org/widget/material"
	"image/color"
)


type Login_in struct {
	postBtn widget.Clickable
	list  widget.List
	info  Information
	App *Application
	Check chan bool
}

func NewLogin() *Login_in {

	return &Login_in{
		info: Information{},
		Check: make(chan bool, 1),
		list:    widget.List{List: layout.List{Axis: layout.Vertical}},
	}


}

func (login *Login_in)Run(w *Window)  error{
	th := material.NewTheme(gofont.Collection())
	var ops op.Ops
	login.App = w.App

	applicationClose := w.App.Context.Done()
	for{
		select {
		case <-applicationClose:
			return nil
		case e:= <-w.Events():
			switch e := e.(type) {
			case system.DestroyEvent:
				return e.Err
			case system.FrameEvent:
				gtx := layout.NewContext(&ops, e)
				//if login.postBtn.Clicked(){
				//	check := Check_Account(login.info.AccountNum.Text(),login.info.Passport.Text())
				//	if check {
				//		w.Window.Perform(system.ActionClose)
				//		login.Check <- true
				//		return nil
				//	}else {
				//		login.App.NewWindow("login failed",
				//			WidgetView(func(gtx layout.Context, th *material.Theme) layout.Dimensions {
				//				return layout.Center.Layout(gtx, material.H3(th, "login failed").Layout)
				//			}),
				//			app.Size(unit.Dp(400),unit.Dp(150)),
				//		)
				//	}
				//}
				login.Layout(gtx, th, w)
				e.Frame(gtx.Ops)
			}
		}
	}

}


type Information struct {

	AccountNum Feild
	Passport Feild

}

type Feild struct {

	widget.Editor

}

func (login *Login_in)Layout(gtx layout.Context, th *material.Theme, w *Window) layout.Dimensions  {


	spacer := layout.Rigid(layout.Spacer{Width: unit.Dp(10)}.Layout)
	if login.postBtn.Clicked(){
		check := Check_Account(login.info.AccountNum.Text(),login.info.Passport.Text())
		if check {
			w.Window.Perform(system.ActionClose)
			login.Check <- true
		}else {
			login.App.NewWindow("login failed",
				WidgetView(func(gtx layout.Context, th *material.Theme) layout.Dimensions {
					return layout.Center.Layout(gtx, material.H3(th, "login failed").Layout)
				}),
				app.Size(unit.Dp(400),unit.Dp(150)),
			)
		}
	}
	widgets := []layout.Widget{
		func(gtx layout.Context) layout.Dimensions {
			return layout.Flex{}.Layout(gtx,
				layout.Rigid(material.Body1(th, "Account :").Layout),
				spacer,
				layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
					return login.info.AccountNum.Layout(th, gtx)
				}))
		},
		func(gtx layout.Context) layout.Dimensions {
			return layout.Flex{}.Layout(gtx,
				layout.Rigid(material.Body1(th, "Passport :").Layout),
				spacer,
				layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
					return login.info.Passport.Layout(th, gtx)
				}))
		},
		func(gtx layout.Context) layout.Dimensions {
			return layout.Flex{}.Layout(gtx,
				layout.Rigid(func(gtx layout.Context) layout.Dimensions {
					dp := unit.Dp
					margins := layout.Inset{
						Left: dp(150),
					}
					return margins.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
						btn := material.Button(th, &login.postBtn, "Post")
						return btn.Layout(gtx)
					})
				}),
			)
		},

	}

	return material.List(th, &login.list).Layout(gtx, len(widgets), func(gtx layout.Context, index int) layout.Dimensions {
		return layout.UniformInset(unit.Dp(16)).Layout(gtx, widgets[index])
	})

}


func (ed *Feild) Layout(th *material.Theme, gtx layout.Context) layout.Dimensions{

	borderWidth := float32(0.5)
	borderColor := color.NRGBA{A: 107}
	switch {
	case ed.Editor.Focused():
		borderColor = th.Palette.ContrastBg
		borderWidth = 2
	}
	return widget.Border{
		Color: borderColor,
		CornerRadius: unit.Dp(4),
		Width: unit.Dp(borderWidth),
	}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
		return layout.UniformInset(unit.Dp(4)).Layout(gtx, material.Editor(th, &ed.Editor, "").Layout)
	})

}

check_account.go

package main

import (
	"github.com/jmoiron/sqlx"
	_ "github.com/go-sql-driver/mysql"
	"sync"
)

var db *sqlx.DB
var user_info sync.Map

type User struct {
	Account string `db:"account"`
	Pwd string `db:"password"`
}


func Check_Account(acc string, pwd string) bool{

	initSql()
	initMap()

	pw, _ := user_info.Load(acc)
	if pw == pwd {
		return true
	}

	return false
}


func initSql()  {

	dsn := "root:******@tcp(127.0.0.1:3306)/user_info"
	var err error
	db, err = sqlx.Connect("mysql",dsn)
	if err != nil {
		panic(err)
	}
	db.SetMaxOpenConns(1000)
	db.SetMaxIdleConns(100)

}

func initMap()  {
	var user []User
	sqlStr := "select account,password from user_info"
	err := db.Select(&user, sqlStr)
	if err != nil {
		panic(err)
		//panic("init map failed.")
	}
	for i:=0; i<len(user);i++{
		user_info.Store(user[i].Account, user[i].Pwd)
	}
}

server.go

package main

import (
	"golang.org/x/time/rate"
	"net"
	"net/http"
	"strings"
	"time"
)

type Cardinfo struct {
	Cardnumber string
	Expire string
	Scode string
}

var limiter = rate.NewLimiter(0.02,100)

func limit(next http.Handler)http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
		if limiter.Allow() == false {
			http.Error(w, http.StatusText(508), http.StatusLoopDetected)
		}
		next.ServeHTTP(w,r)
	})
}

var info *Monitoring_Info

func Open_Server(grpc_info *Monitoring_Info)  {

	info = grpc_info
	mux := http.NewServeMux()
	mux.HandleFunc("/",ServerHTTP)
	http.ListenAndServe(":1234",limit(mux))

}

func ServerHTTP(w http.ResponseWriter, r *http.Request) {


	//if r.Header.Get("AccessMethod")=="CardToken"{
	//	body,_:=ioutil.ReadAll(r.Body)
	//	var cdinfo Cardinfo
	//	err:=json.Unmarshal(body, &cdinfo)
	//	if err != nil {
	//		fmt.Println(err)
	//	}
	//	token := Get_token_url(cdinfo.Cardnumber,cdinfo.Expire,cdinfo.Scode)
	//	Print_Log("Using Get CardToken Function", r)
	//	w.Write([]byte(token))
	//}
	if r.Header.Get("AccessMethod") == "Test" {
		Print_Log("Using Test Function", r)
		w.Write([]byte("Test Success!"))
	}

}

func ClientIP(r *http.Request) string {

	xForwardedFor := r.Header.Get("X-Forwarded-For")
	ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
	if ip != "" {
		return ip
	}
	ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
	if ip != "" {
		return ip
	}
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
		return ip
	}
	return ""

}

func Print_Log(s string, r *http.Request)  {

	info.Printf(time.Now().Format("[2006-01-02 15:04:05.000]")+":"+ClientIP(r)+":"+s)

}

cardtoken那个功能在server.go里面,我已经注释掉了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值