redis走websocket的方法

redis目前最新版本7.2 依旧不支持websocket.不过看核心团队已经准备开始支持。

websocket 更容易部署到servless等场景,也更加容易通过cdn 防火墙之类的管理。

用golang可以简单的反向代理过去。

因为逻辑简单,所以性能还是很强的。只是增加了多于的网络的开支。在目前情况下 过渡使用是没有问题的。

另外有一个国人写的 用go实现的redis: https://github.com/HDT3213/godis 可以简单的修改为ws

不过目前还不支持 steam 。

当然目前没有可用的 客户端,需要自己手撸。但是命令直接转发效果是一样的。

下面是一个简单的实现,你也可以完成AUTH部分 方便使用acl。

这样反代后 对 不支持 集群的客户端 也非常友好

客户端测试

1
2
3
4
> wscat -c ws://localhost:8080/websocket
Connected (press CTRL+C to quit)
> set wstest 123
< OK
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strings"

	"github.com/gorilla/websocket"
	"github.com/redis/go-redis/v9"
)

var redisClient *redis.ClusterClient

func init() {
	// 初始化Redis集群客户端
	redisClient = redis.NewClusterClient(&redis.ClusterOptions{
		Addrs:    []string{"localhost:6001", "localhost:6002", "localhost:6003", "localhost:6004", "localhost:6005", "localhost:6006"}, // 替换为真实的Redis节点地址
		Password: "ut97WiD9SvUQtJ",                                                                                                     // 替换为你的Redis密码
	})
}

func main() {
	http.HandleFunc("/websocket", handleWebSocket)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
	// 升级HTTP连接为WebSocket连接
	upgrader := websocket.Upgrader{}
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println("WebSocket upgrade failed:", err)
		return
	}
	defer conn.Close()

	for {
		// 读取WebSocket消息
		_, msg, err := conn.ReadMessage()
		if err != nil {
			log.Println("WebSocket read failed:", err)
			break
		}
		// 转发请求到Redis集群
		inputArgs := strings.Fields(string(msg))
		args := make([]interface{}, len(inputArgs))
		for i, v := range inputArgs {
			args[i] = v
		}
		res, err := redisClient.Do(context.Background(), args...).Result()
		if err != nil {
			log.Println("Redis publish failed:", err)
			conn.WriteMessage(websocket.TextMessage, []byte(err.Error()))
			break
		}
		fmt.Println("res", res)
		fmt.Printf("Received message: %s\n", msg)

		// 发送响应给WebSocket客户端
		err = conn.WriteMessage(websocket.TextMessage, []byte(res.(string)))
		if err != nil {
			log.Println("WebSocket write failed:", err)
			break
		}
	}
}
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计