2024-08-15



package main
 
import (
    "fmt"
    "github.com/nats-io/nats.go"
    "log"
    "time"
)
 
func main() {
    // 连接到NATS服务器
    nc, err := nats.Connect(nats.DefaultURL)
    if err != nil {
        log.Fatal(err)
    }
    defer nc.Close()
 
    // 请求-响应模式: 发送一个请求并等待响应
    sub, err := nc.SubscribeSync("request", func(m *nats.Msg) {
        nc.Publish(m.Reply, []byte("NATS Request Response"))
    })
    if err != nil {
        log.Fatal(err)
    }
    defer sub.Unsubscribe()
    
    // 发送请求并等待响应
    msg, err := nc.Request("request", []byte("Hey NATS"), 1*time.Second)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Received Response: %s\n", string(msg.Data))
}

这段代码演示了如何使用Go语言和NATS消息中间件库来创建一个简单的请求-响应模式的消息系统。首先,它连接到NATS服务器,然后创建一个同步订阅者来处理名为"request"的主题的消息,并发送响应。最后,它发送一个请求并等待响应,并将接收到的响应打印出来。

2024-08-15



package main
 
import (
    "context"
    "fmt"
    "log"
    "net/http"
 
    "github.com/99designs/gqlgen/graphql/handler"
    "github.com/99designs/gqlgen/graphql/playground"
    "github.com/go-chi/chi"
    "github.com/go-chi/chi/middleware"
    "github.com/gorilla/mux"
    "github.com/rs/cors"
)
 
type Query struct{}
 
// This function is not important for the purpose of this example.
// It simply mocks a function to handle a GraphQL query.
func (q *Query) Hello() string {
    return "Hello, world!"
}
 
func main() {
    // 初始化GraphQL引擎
    execSchema := generated.NewExecutableSchema(generated.Config{Resolvers: &resolvers.Resolver{}})
    h := handler.New(execSchema)
 
    // 创建一个Go语言的net/http服务器
    srv := &http.Server{Addr: ":8080"}
    
    // 创建一个Go语言的路由器
    r := mux.NewRouter()
 
    // 为路由器添加GraphQL Playground
    r.Handle("/", playground.Handler("GraphQL playground", "/query"))
 
    // 为路由器添加GraphQL查询端点
    r.Handle("/query", h)
 
    // 设置服务器的路由为路由器
    srv.Handler = r
 
    // 启动服务器并监听错误
    log.Fatal(srv.ListenAndServe())
}

这个代码示例展示了如何在Go语言项目中使用gqlgen库来创建一个GraphQL服务器,并将其与一个基本的mux路由器集成。它提供了一个简单的查询函数,并设置了GraphQL的Playground,使得用户可以在浏览器中进行GraphQL查询。这个示例简洁而完整,可以作为开发者实现GraphQL服务器的参考。

2024-08-15

在Golang中,net/http标准库提供了Request类型,它代表了一个HTTP请求。以下是Request类型的一些常见用法:

  1. 获取请求的方法:



req, _ := http.NewRequest("GET", "http://example.com", nil)
fmt.Println(req.Method) // 输出:GET
  1. 获取请求的URL:



req, _ := http.NewRequest("GET", "http://example.com", nil)
fmt.Println(req.URL) // 输出:http://example.com
  1. 获取请求头信息:



req, _ := http.NewRequest("GET", "http://example.com", nil)
if req.Header != nil {
    for k, v := range req.Header {
        fmt.Println(k, v)
    }
}
  1. 设置或修改请求头信息:



req, _ := http.NewRequest("GET", "http://example.com", nil)
req.Header.Set("Content-Type", "application/json")
fmt.Println(req.Header.Get("Content-Type")) // 输出:application/json
  1. 获取请求体(Body):



req, _ := http.NewRequest("GET", "http://example.com", bytes.NewBuffer([]byte("{\"name\":\"John\"}")))
body, _ := ioutil.ReadAll(req.Body)
fmt.Println(string(body)) // 输出:{"name":"John"}
  1. 获取客户端发送的Cookie:



req, _ := http.NewRequest("GET", "http://example.com", nil)
req.AddCookie(&http.Cookie{Name: "go_cookie", Value: "test_cookie"})
for _, cookie := range req.Cookies() {
    fmt.Println(cookie.Name, cookie.Value) // 输出:go_cookie test_cookie
}

以上代码片段展示了如何使用net/http标准库中的Request类型的一些常用属性和方法。在实际应用中,你可以根据需要使用这些属性和方法来处理HTTP请求。

2024-08-15



package main
 
import (
    "crypto/des"
    "crypto/md5"
    "crypto/rand"
    "encoding/hex"
    "fmt"
    "io"
)
 
// 使用TripleDES进行加密
func EncryptTripleDES(key []byte, text []byte) ([]byte, error) {
    block, err := des.NewTripleDESCipher(key)
    if err != nil {
        return nil, err
    }
    plaintext := pad(text)
    iv := key[:des.BlockSize]
    encrypter := des.NewCipher(block)
    encrypted := make([]byte, len(plaintext))
    encrypter.Encrypt(encrypted, plaintext)
    return encrypted, nil
}
 
// 使用TripleDES进行解密
func DecryptTripleDES(key []byte, text []byte) ([]byte, error) {
    block, err := des.NewTripleDESCipher(key)
    if err != nil {
        return nil, err
    }
    iv := key[:des.BlockSize]
    decrypter := des.NewCipher(block)
    decrypted := make([]byte, len(text))
    decrypter.Decrypt(decrypted, text)
    return unpad(decrypted), nil
}
 
// 使用MD5生成密钥
func GenerateKey(password string) []byte {
    hasher := md5.New()
    hasher.Write([]byte(password))
    return hasher.Sum(nil)
}
 
// 填充数据至8的倍数
func pad(buf []byte) []byte {
    padNum := des.BlockSize - (len(buf) % des.BlockSize)
    padText := bytesRepeat([]byte{byte(padNum)}, padNum)
    return append(buf, padText...)
}
 
// 移除填充数据
func unpad(buf []byte) []byte {
    length := len(buf)
    if length == 0 {
        return buf
    }
    n := int(buf[length-1])
    return buf[:length-n]
}
 
// 创建一个重复的字节切片
func bytesRepeat(b []byte, n int) []byte {
    bb := make([]byte, len(b)*n)
    for i := 0; i < n; i++ {
        copy(bb[i*len(b):(i+1)*len(b)], b)
    }
    return bb
}
 
func main() {
    // 示例密码
    password := "secret"
    // 原始数据
    originalData := []byte("Hello, TripleDES!")
    // 生成密钥
    key := GenerateKey(password)
    
    // 加密数据
    encryptedData, err := EncryptTripleDES(key, originalData)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Encrypted: %x\n", encryptedData)
    
    // 解密数据
    decryptedData, err := DecryptTripleDES(key, encryptedData)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Decrypted: %s\n", decryptedData)
}

这段代码提供了使用Go语言进行TripleDES加密和解密的一个简单示例。首先,使用MD5生成密钥。然后,使用EncryptTripleDES函数进行加密,使用DecryptTripleDES函数进行解密。代码中包含了填充和移除填充的必要操作,以确保数据块的大小符合加密算法的要求。

2024-08-15

在Go语言中,可以使用gorilla/session库来实现支持多种存储方式的session管理。以下是一个使用gorilla/session库的示例,它演示了如何使用cookie和Redis作为存储方式。

首先,需要安装gorilla/session库:




go get github.com/gorilla/session
go get github.com/gorilla/securecookie

如果使用Redis作为存储,还需要安装redis的Go客户端:




go get github.com/go-redis/redis

以下是一个简单的示例代码,演示了如何使用gorilla/session库:




package main
 
import (
    "net/http"
    "github.com/gorilla/mux"
    "github.com/gorilla/sessions"
    "github.com/go-redis/redis"
)
 
var (
    // 使用cookie存储session
    store = sessions.NewCookieStore([]byte("something-very-secret"))
 
    // 使用Redis存储session
    // redisClient = redis.NewClient(&redis.Options{
    //     Addr:     "localhost:6379",
    //     Password: "", // no password set
    //     DB:       0,  // use default DB
    // })
    // store = sessions.NewRedisStore(10*time.Minute, redisClient)
)
 
func main() {
    r := mux.NewRouter()
    r.HandleFunc("/set", setSession).Methods("GET")
    r.HandleFunc("/get", getSession).Methods("GET")
    http.ListenAndServe(":8080", r)
}
 
func setSession(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "session-name")
    session.Values["foo"] = "bar"
    session.Save(r, w)
}
 
func getSession(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "session-name")
    foo := session.Values["foo"]
    w.Write([]byte(foo.(string)))
}

在这个示例中,store变量被定义为使用sessions.NewCookieStore创建的cookie存储。如果想要使用Redis作为存储,可以取消注释Redis存储的定义,并注释掉cookie存储的定义。

setSession函数设置了一个名为foo的session值,而getSession函数获取并返回这个值。

这个示例演示了如何使用gorilla/session库来管理session,并且如何根据需要选择不同的存储方式。

2024-08-15

在这个教程中,我们将会创建一个API接口来处理用户登出操作,并在客户端使用JWT进行验证。

首先,我们需要在User控制器中添加登出方法:




// app/controller/User.php
 
namespace app\controller;
 
use think\Controller;
use think\facade\Session;
 
class User extends Controller
{
    // ...
 
    // 登出接口
    public function logout()
    {
        // 清除session
        Session::clear();
 
        // 返回登出成功信息
        return json(['code' => 200, 'msg' => '登出成功', 'data' => []]);
    }
}

然后,我们需要在Auth中间件中添加对JWT的支持,以便在登出时验证JWT:




// app/middleware/Auth.php
 
namespace app\middleware;
 
use think\facade\Request;
use Firebase\JWT\JWT;
 
class Auth
{
    public function handle($request, \Closure $next)
    {
        // 获取header中的authorization参数
        $authorization = $request->header('authorization');
 
        if (!$authorization) {
            return json(['code' => 401, 'msg' => '未提供Token', 'data' => []]);
        }
 
        // 解析JWT
        try {
            $decoded = JWT::decode($authorization, config('jwt.secret'), [config('jwt.alg')]);
            $request->userId = $decoded->userId;
        } catch (\Exception $e) {
            return json(['code' => 401, 'msg' => 'Token无效', 'data' => []]);
        }
 
        // 继续执行下一个中间件
        return $next($request);
    }
}

最后,我们需要在全局中间件配置中注册Auth中间件,使其在每次请求时都会验证JWT:




// app/middleware.php
 
return [
    // ...
    'auth' => \app\middleware\Auth::class,
];

这样,我们就完成了登出接口的创建和JWT验证的集成。当用户请求登出接口时,我们会清除session,并返回登出成功的信息。在实际的APP请求中,我们会在客户端保存JWT,并在每次请求时携带这个Token,服务端会对Token进行验证。如果Token无效或未提供,会返回错误信息。

2024-08-15

GoRequests 是一个第三方的 Go 语言 HTTP 库,它提供了一种简洁的方式来发送 HTTP 请求。

安装 GoRequests:




go get -u github.com/imroc/req

基本使用示例:




package main
 
import (
    "fmt"
    "github.com/imroc/req"
)
 
func main() {
    // 发送 GET 请求
    resp, err := req.Get("http://httpbin.org/get")
    if err != nil {
        panic(err)
    }
    fmt.Println(resp.String())
 
    // 发送 POST 请求
    resp, err = req.Post("http://httpbin.org/post", req.BodyJSON(&map[string]string{"key": "value"}))
    if err != nil {
        panic(err)
    }
    fmt.Println(resp.String())
}

这段代码首先导入了 req 包,然后在 main 函数中发送了一个 GET 和一个 POST 请求。它演示了如何使用 GoRequests 发送请求并处理可能出现的错误。通过 resp.String() 方法,我们可以获取响应的字符串形式。

2024-08-15

以下是五个流行的Go语言REST API框架,并附有简短的描述和示例代码。

  1. Gin

    Gin是一个用Go编写的web框架,它以简单的API为主要设计原则提供功能。




package main
 
import "github.com/gin-gonic/gin"
 
func main() {
    r := gin.Default()
    r.GET("/hello", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "Hello world!"})
    })
    r.Run() // 默认在0.0.0.0:8080启动服务
}
  1. Echo

    Echo是一个高性能的Go Web框架,它以路由功能为核心。




package main
 
import (
    "net/http"
    "github.com/labstack/echo"
)
 
func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    e.Start(":8080")
}
  1. Iris

    Iris是另一个Go语言的高性能Web框架,它以性能优越和易用性为设计原则。




package main
 
import "github.com/kataras/iris"
 
func main() {
    app := iris.Default()
    app.Get("/", func(ctx iris.Context) {
        ctx.JSON(iris.Map{"message": "Hello world!"})
    })
    app.Listen(":8080")
}
  1. Beego

    Beego是一个开源的Go语言网络框架,它具有丰富的功能,例如路由、MVC、日志、配置管理、数据库操作、缓存等。




package main
 
import "github.com/astaxie/beego"
 
type MainController struct {
    beego.Controller
}
 
func (c *MainController) Get() {
    c.Data["json"] = map[string]string{"message": "Hello world!"}
    c.ServeJSON()
}
 
func main() {
    beego.Router("/", &MainController{})
    beego.Run()
}
  1. Revel

    Revel是一个高生产力的Go语言Web框架,它以简单性和高生产力为设计原则。




package controllers
 
import "github.com/revel/revel"
 
type AppController struct {
    *revel.Controller
}
 
func (c AppController) Hello() revel.Result {
    return c.RenderJson(map[string]string{"message": "Hello world!"})
}

以上代码片段提供了不同Go REST API框架的简单示例。每个示例都创建了一个基础的API,监听8080端口,并对根URL的GET请求进行处理,返回一个简单的JSON响应。开发者可以根据具体需求进一步扩展这些示例。

2024-08-15



package main
 
import (
    "fmt"
    "github.com/polarismesh/polaris-go/api"
    "github.com/polarismesh/polaris-go/pkg/config"
    "time"
)
 
func main() {
    // 初始化Polaris客户端配置
    cfg := config.ClientConfig{
        Token:       "your-token",
        Master:      "https://polaris.example.com",
        Insecure:    false,
        AccessKey:   "your-access-key",
        SecretKey:   "your-secret-key",
        RegionId:    "your-region-id",
        DataCenter:  "your-data-center",
        ClusterId:   "your-cluster-id",
        Namespace:   "your-namespace",
        Pod:         "your-pod-name",
        ServiceName: "your-service-name",
    }
 
    // 创建Polaris客户端
    client, err := api.NewClient(cfg)
    if err != nil {
        panic(err)
    }
 
    // 服务注册
    err = client.RegisterInstance(api.Instance{
        Host: "your-host-ip",
        Port: 8080,
        Healthy: api.HealthInfo{
            CheckMode:    api.HTTP,
            CheckURL:     "http://your-host-ip:8080/health",
            CheckInterval: 30 * time.Second,
        },
        Weight: 100,
        Enable: true,
        Metadata: map[string]string{
            "version": "1.0",
        },
    })
    if err != nil {
        panic(err)
    }
 
    // 服务发现
    instances, err := client.FindInstances("your-service-name")
    if err != nil {
        panic(err)
    }
    for _, instance := range instances {
        fmt.Printf("Instance: %+v\n", instance)
    }
}

这段代码展示了如何使用polaris-go客户端库进行服务注册和发现。首先,它配置了客户端所需的参数,然后创建了一个Polaris客户端实例。接下来,它演示了如何注册服务实例,并定义了健康检查的相关信息。最后,它通过服务名称查找服务实例,并打印出每个实例的详细信息。这个过程是Polaris服务注册发现的一个基本示例。

2024-08-15



package main
 
import (
    "fmt"
    "github.com/elliotchance/categorize-golang-slices/numeric"
)
 
func main() {
    // 创建一个int类型的切片
    slice := []int{1, 2, 3, 4, 5}
 
    // 使用categorize-golang-slices库中的函数来判断切片是否全为正数
    allPositive := numeric.AllPositiveInt(slice)
 
    // 打印结果
    fmt.Println("Is the slice all positive?", allPositive)
}

这段代码演示了如何使用categorize-golang-slices库中的numeric.AllPositiveInt函数来判断一个整数切片是否全部由正数组成。它首先创建了一个包含正整数的切片,然后调用库函数来判断,并打印结果。这个例子简单明了地展示了如何使用该库,并且可以作为开发者学习和使用该库的一个很好的起点。