分类 golang 下的文章

graphql 有 Schema,Object,String,Int,Boolean 等元素组成。其中 Schema 包含 Query,Mutation,Subscription 三个 Object 类型的成员,对应 graphql 的三类操作。

var schema, _ = graphql.NewSchema(graphql.SchemaConfig{
    Query:    rootQuery, // 针对查询
    Mutation: rootMutation, // 针对写操作
    Subscription: rootSubscription, // 暂时没研究过,跟实时通讯相关
})

// 定义根 QueryObject
var rootQuery = graphql.NewObject(graphql.ObjectConfig{
    Name:        "RootQuery", // Object 的类型名,必须符合变量规则,不能包含空格
    Fields: graphql.Fields{ // 该对象所包含的字段列表
        "memos": &graphql.Field{
            Type: MemoType, // 类型是下面的自定义类型
            Args: graphql.FieldConfigArgument{
                "content": &graphql.ArgumentConfig{
                    Type: graphql.String,
                },
            },
            // 每个字段可以提供一个解析函数,用来告知 graphql 如何获取数据
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                return nil, nil
            },
        },
    }
}

// 自定义Object
var MemoType = graphql.NewObject(graphql.ObjectConfig{
    Name:        "MemoType",
    Fields: graphql.Fields{
        "id": &graphql.Field{
            Name: "id",
            Type: graphql.Int,
        },
        "content": &graphql.Field{
            Name: "content",
            Type: graphql.String,
        },
    },
})
javascript调用

axios.post("/graphql", {
    "query": `mutation createMemo($content: String) { 
        createMemo(content: $content) {
            id
            content
        }
    }`,
    "variables": {
        content: "哈哈"
    }
}).then((resp) => {
    if (resp.status == 200 && !resp.data.errors) {
        console.log(resp.data.data)
    }
});

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    url := "https://api.64clouds.com/v1/getServiceInfo?veid=823669&api_key=private_xt5IHIYNAhuYxkFlvLpCWTGc"
    resp, err := http.Get(url)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    var data map[string]interface{}
    err = json.NewDecoder(resp.Body).Decode(&data)
    if err != nil {
        panic(err)
    }

    data_counter, ok := data["data_counter"].(float64)
    if !ok {
        return
    }
    v := data_counter / 1024.0 / 1024.0 / 1024.0
    fmt.Printf("%.2fGB/500.00GB\n", v)
}

KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。

package main

import (
    kcp "github.com/xtaci/kcp-go"
)

func main() {
    // 服务端
    l, _ := kcp.Listen(":7777")
    c, _ := l.Accept()
    
    // 客户端
    c, _ := kcp.Dial("localhost:7777")
}

其中 l, c 都实现了 net 包中的接口,所以可以很方便的对接现有代码。
kcp 速度快且支持加密,在 socks 的支持下,貌似做一些坏事。

package main

import (
    socks5 "github.com/armon/go-socks5"
)

func main() {
    s, _ := socks5.New(&socks5.Config{})
    s.ListenAndServe("tcp", ":6666")
}

type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chan struct{}
    Err() error
    Value(key interface{}) interface{}
}

ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
<-ctx.Done()

Deadline 返回一个time.Time,表示当前Context应该结束的时间,ok则表示有结束时间
Done 当Context被取消或者超时时候返回的一个close的channel,告诉给context相关的函数要停止当前工作然后返回了。
Err context被取消的原因
Value context实现共享数据存储的地方,是协程安全的