websocket proto3 test

proto3 Websocket 性能测试

分别对 proto3 原生字段和proto3 +json 通用的content字段做对比测试

proto3 +json 通用字段测试

服务端代码

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
69
70
71
72
73
74
75
76
77
package main

import (
"encoding/json"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
"log"
"net/http"
"proto3Test/testproto"
"time"
)

var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}

var fastTime = time.Now()
var lastTIme = time.Now()
var fast = 0

type JsonEntity struct {
BillID string `json:"billID"`
BookId string `json:"bookId"`
Money int `json:"money"`
CrtUser string `json:"crtUser"`
Time int `json:"time"`
Category string `json:"category"`
Type int `json:"type"`
Remark string `json:"remark"`
}

var count = 0

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
defer conn.Close()

for {
_, p, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
if fast == 0 {
fast = 1
fastTime = time.Now()
}
var message testproto.WsMsgJson
err = proto.Unmarshal(p, &message)
if err != nil {
log.Println("Error unmarshaling message.testproto:", err)
continue
}
lastTIme = time.Now()
var jsonentity JsonEntity
err = json.Unmarshal([]byte(message.Content), &jsonentity)
if err != nil {
fmt.Println(err.Error())
}
count++
fmt.Printf("Received message:%d, %v\n", count, message)
elapsedTime := lastTIme.Sub(fastTime)
fmt.Printf("elapsedtime %s\n", elapsedTime)
}
}

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

客户端代码

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
69
70
71
72
73
74
75
76
package main

import (
"encoding/json"
"fmt"
"github.com/gorilla/websocket"
"google.golang.org/protobuf/proto"
"log"
"os"
"os/signal"
"proto3TestClient/testproto"
)

type JsonEntity struct {
BillID string `json:"billID"`
BookId string `json:"bookId"`
Money int `json:"money"`
CrtUser string `json:"crtUser"`
Time int `json:"time"`
Category string `json:"category"`
Type int `json:"type"`
Remark string `json:"remark"`
}

func main() {
// WebSocket 服务器地址
serverAddr := "ws://localhost:8080/ws"

// 建立 WebSocket 连接
conn, _, err := websocket.DefaultDialer.Dial(serverAddr, nil)
if err != nil {
log.Fatal("Error connecting to WebSocket:", err)
}
defer conn.Close()

// 用于处理关闭信号的通道
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
jsonEntity := JsonEntity{
BillID: "BillID12345",
BookId: "BookId67890",
Money: 100,
CrtUser: "John Doe",
Time: 1638460800,
Category: "Expense",
Type: 1,
Remark: "Example remark",
}
jsonStr, _ := json.Marshal(jsonEntity)
// 创建 Proto3 消息
message := testproto.WsMsgJson{
Id: "123456789a",
Type: testproto.Types_ADD_BILL,
Timestamp: 1232133221313321321,
FromId: "hao88.cloud",
ToId: "a,b,c,d,e,f",
Content: string(jsonStr),
}

// 将 Proto3 消息编码为字节数组
messageBytes, err := proto.Marshal(&message)
if err != nil {
log.Fatal("Error marshaling Proto3 message:", err)
}
var count = 0

for count < 10000 {
// 发送 Proto3 消息到服务器
err = conn.WriteMessage(websocket.BinaryMessage, messageBytes)
if err != nil {
log.Fatal("Error writing Proto3 message:", err)
}
count++
fmt.Printf("send count =%d \n", count)
}
}

proto3 WsMsgJson原始类型+Content JSON通用字段

一万次测试

1.0092289s
1.00941s
982.7023ms
960.6469ms
1.0632747s
1.0033288s

十万次测试

26.848908s
26.1620038s
26.7516639s

proto3 原生字段测试

服务端代码

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
69
70
71
package main

import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
"log"
"net/http"
"proto3Test/testproto"
"time"
)

var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}

var fastTime = time.Now()
var lastTIme = time.Now()
var fast = 0

type JsonEntity struct {
BillID string `json:"billID"`
BookId string `json:"bookId"`
Money int `json:"money"`
CrtUser string `json:"crtUser"`
Time int `json:"time"`
Category string `json:"category"`
Type int `json:"type"`
Remark string `json:"remark"`
}

var count = 0

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
defer conn.Close()

for {
_, p, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
if fast == 0 {
fast = 1
fastTime = time.Now()
}
var message testproto.AddBill
err = proto.Unmarshal(p, &message)
if err != nil {
log.Println("Error unmarshaling message.testproto:", err)
continue
}
lastTIme = time.Now()
count++
fmt.Printf("Received message:%d, %v\n", count, message)
elapsedTime := lastTIme.Sub(fastTime)
fmt.Printf("elapsedtime %s\n", elapsedTime)
}
}

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

客户端代码

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
69
70
71
72
73
74
75
76
77
78
package main

import (
"fmt"
"github.com/gorilla/websocket"
"google.golang.org/protobuf/proto"
"log"
"os"
"os/signal"
"proto3TestClient/testproto"
)

type JsonEntity struct {
BillID string `json:"billID"`
BookId string `json:"bookId"`
Money int `json:"money"`
CrtUser string `json:"crtUser"`
Time int `json:"time"`
Category string `json:"category"`
Type int `json:"type"`
Remark string `json:"remark"`
}

func main() {
// WebSocket 服务器地址
serverAddr := "ws://localhost:8080/ws"

// 建立 WebSocket 连接
conn, _, err := websocket.DefaultDialer.Dial(serverAddr, nil)
if err != nil {
log.Fatal("Error connecting to WebSocket:", err)
}
defer conn.Close()

// 用于处理关闭信号的通道
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
var wsMsgList []*testproto.WsMsg
// 创建一个单独的 WsMsg 对象
singleWsMsg := &testproto.WsMsg{
Id: "123456789a",
Type: testproto.Types_ADD_BILL,
Timestamp: 1232133221313321321,
FromId: "hao88.cloud",
ToId: "a,b,c,d,e,f",
}
wsMsgList = append(wsMsgList, singleWsMsg)
// 创建 Proto3 消息
message := testproto.AddBill{
WsMsg: wsMsgList,
BillID: "BillID12345",
BookId: "BookId67890",
Money: 100,
CrtUser: "John Doe",
Time: 1638460800,
Category: "Expense",
Type: 1,
Remark: "Example remark",
}

// 将 Proto3 消息编码为字节数组
messageBytes, err := proto.Marshal(&message)
if err != nil {
log.Fatal("Error marshaling Proto3 message:", err)
}
var count = 0

for count < 10000 {
// 发送 Proto3 消息到服务器
err = conn.WriteMessage(websocket.BinaryMessage, messageBytes)
if err != nil {
log.Fatal("Error writing Proto3 message:", err)
}
count++
fmt.Printf("send count =%d \n", count)
}
}

proto3 AddBill 原始类型

一万次测试

922.3579ms
896.741ms
1.0403121s
899.4702ms

十万次测试

13.4137169s
13.1905226s
13.2676373s


websocket proto3 test
http://example.com/2023/11/29/program/websocketproto3test/
作者
hao88
发布于
2023年11月29日
许可协议