2020年7月

beego validation无效、失效 golang tag标签的一个坑


来看看结构体

这样 自己用table键吧tag标签搞得整整齐齐的

type People struct {
    Key     string `json:"key"         form:"key"         valid:"Required"`         //id值
    Name    string `json:"name"     form:"name"     valid:"Required"`         //名字
    Idcard  string `json:"idcard"     form:"idcard"     valid:"Length(18)"`   //身份证
    Iccard  string `json:"iccard"     form:"iccard"`                       //IC卡号
    Sex     int    `json:"sex"         form:"sex"         valid:"Required;Numeric"` //1男 2女
    Picture string `json:"picture"     form:"picture"     valid:"Base64"`     //照片 base64
}

然后我们反射一下看看结果

package main

import (
    "fmt"
    "reflect"
)

type People struct {
    Key     string `json:"key"         form:"key"         valid:"Required"`         //id值
    Name    string `json:"name"     form:"name"     valid:"Required"`         //名字
    Idcard  string `json:"idcard"     form:"idcard"     valid:"Length(18)"`   //身份证
    Iccard  string `json:"iccard"     form:"iccard"`                       //IC卡号
    Sex     int    `json:"sex"         form:"sex"         valid:"Required;Numeric"` //1男 2女
    Picture string `json:"picture"     form:"picture"     valid:"Base64"`     //照片 base64
}

func main() {

    people := People{
        Key: "ccc",
    }

    t := reflect.TypeOf(people)

    for i := 0; i < t.NumField(); i++ {
        key := t.Field(i)
        valid := key.Tag.Get("valid")
        fmt.Println(valid)
    }

}

果然输出结果是空的

2020-07-23T00:50:54.png

然后我们把结构体中的tag标签用空格分开

2020-07-23T00:52:37.png

再执行 反射成功!

2020-07-23T00:53:09.png


结论:

结构体tag标签中不能使用table键(可以用多个空格键,或者不用空格)

centos安装brook教程


1.安装Nami
curl https://raw.githubusercontent.com/txthinking/nami/master/install.sh | bash && sleep 6 && exec -l $SHELL
2.通过Nami安装brook
nami install github.com/txthinking/brook

2020-07-19T02:42:53.png

3.后台运行ws模式的brook
nohup brook wsserver -l 0.0.0.0:端口 -p 密码 &

如果连接不上 需要关闭防火墙或者端口放行


golang github死锁挑战二


https://github.com/GoesToEleven/GolangTraining/blob/master/22_go-routines/10_deadlock-challenges/03_deadlock-challenge/main.go

package main

import (
    "fmt"
)

func main() {

    c := make(chan int)

    go func() {
        for i := 0; i < 10; i++ {
            c <- i
        }
    }()

    fmt.Println(<-c)

}
//为什么只显示零?
//并且该怎么做才能打印所有0-9个数字?

解决方法一

停止携程 用for读取通道

package main

import (
    "fmt"
)

func main() {

    c := make(chan int)

    go func() {
        for i := 0; i < 10; i++ {
            c <- i
        }
        //关闭通道
        close(c)
    }()

    for {
        x, ok := <-c  //如果不关闭通道的话 这里会导致死锁,因为通道中没有值写入 这里一直一直一直会等待导致死锁
        if !ok { //判断通道是否关闭
            return
        }
        fmt.Println(x, ok)
    }

}

解决方法二

停止携程 用使用for-range读取通道

package main

import (
    "fmt"
)

func main() {

    c := make(chan int)

    go func() {
        for i := 0; i < 10; i++ {
            c <- i
        }
        //关闭通道
        close(c)
    }()

    for v := range c {
        fmt.Println(v)
    }
}

兴趣话题

下面代码为什么 会无限输出000000000000000000000000000.......?

package main

import (
    "fmt"
)

func main() {

    c := make(chan int)

    go func() {
        for i := 0; i < 10; i++ {
            c <- i
        }
        //关闭通道
        close(c)
    }()

    for {
        fmt.Println(<-c) //为什么会一直输出00000000000000?
    }
    // for v := range c {
    //     fmt.Println(v)
    // }
}

golang github死锁挑战一


https://github.com/GoesToEleven/GolangTraining/tree/master/22_go-routines/10_deadlock-challenges

package main

import (
    "fmt"
)

func main() {
    c := make(chan int)
    c <- 1
    fmt.Println(<-c)
}
//这会导致死锁。
//您能确定原因吗?
//而您将如何解决?

解决方法一:

通道加缓存

package main

import (
    "fmt"
)

func main() {
    c := make(chan int,1)
    c <- 1
    fmt.Println(<-c)
}

解决方法二:

加协程

package main

import (
    "fmt"
)

func main() {
    c := make(chan int)
    go func() {
        c <- 1
    }()
    fmt.Println(<-c)
}

golang websocket并发


WsConn *websocket.Conn 并发不安全 不能同时写
panic: concurrent write to websocket connection

package cws
 
import (
    "errors"
    "github.com/gorilla/websocket"
    "sync"
)
 
//封装websocket并发读写操作
 
type Connection struct {
    WsConn    *websocket.Conn
    InChan    chan []byte
    OutChan   chan models.BayDataS
    CloseChan chan byte
    Mutex     sync.Mutex
    IsClosed  bool
}
 
func InitConnection(wsConn *websocket.Conn) (conn *Connection, err error) {
    conn = &Connection{
        WsConn:    wsConn,
        InChan:    make(chan []byte, 1000),
        OutChan:   make(chan []byte, 1000),
        CloseChan: make(chan byte, 1),
    }
    //读协程
    go conn.ReadLoop()
    //写协程
    go conn.WriteLoop()
    return
}
 
func (conn *Connection) ReadMess() (data []byte, err error) {
    select {
    case data = <-conn.InChan:
    case <-conn.CloseChan:
        err = errors.New("connection is closed")
    }
    return
}
 
func (conn *Connection) WriteMes(data []byte) (err error) {
    select {
    case conn.OutChan <- data:
    case <-conn.CloseChan:
        err = errors.New("connection is closed")
    }
    return
}
 
func (conn *Connection) Close() {
    conn.WsConn.Close() //本身线程安全,可重入
    //加锁,只能执行一次
    conn.Mutex.Lock()
    if !conn.IsClosed {
        close(conn.CloseChan)
        conn.IsClosed = true
    }
}
 
//具体实现读消息
func (conn *Connection) ReadLoop() {
    var (
        data []byte
        err  error
    )
    for {
        if _, data, err = conn.WsConn.ReadMessage(); err != nil {
            goto ERR
        }
        select {
        case conn.InChan <- data:
        case <-conn.CloseChan:
            goto ERR
        }
    }
ERR:
    conn.Close()
}
 
//具体实现写消息
func (conn *Connection) WriteLoop() {
    var (
        data models.BayDataS
        err  error
    )
    for {
        select {
        case data = <-conn.OutChan:
        case <-conn.CloseChan:
            goto ERR
        }
        if err = conn.WsConn.WriteMessage(websocket.TextMessage, data); err != nil {
            goto ERR
        }
    }
ERR:
    conn.Close()
}

golang base64保存文件


golang:


/**
 * @description: base64 文件保存
 * @param 路径,文件名,内容
 * @return:
 */
func Base64ToFile(path, fileName, base64Str string) (err error) {
    err = os.MkdirAll(path, 0777) //创建目录
    if err != nil {
        return err
    }

    ddd, err := base64.StdEncoding.DecodeString(base64Str)
    if err != nil {
        return err
    }

    err = ioutil.WriteFile(path+fileName, ddd, 0666) //buffer输出文件中(不做处理,直接写到文件)
    if err != nil {
        return err
    }
    return nil
}