Skip to content

Commit 69cccde

Browse files
authored
Merge pull request #15 from WqyJh/feat-ping
feat: support websocket ping
2 parents 138a4af + bb0359b commit 69cccde

File tree

10 files changed

+60
-8
lines changed

10 files changed

+60
-8
lines changed

conn.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ func (c *Conn) ReadMessage(ctx context.Context) (ServerEvent, error) {
5858
return event, nil
5959
}
6060

61+
// Ping sends a ping message to the WebSocket connection.
62+
func (c *Conn) Ping(ctx context.Context) error {
63+
return c.conn.Ping(ctx)
64+
}
65+
6166
// ConnHandler is a handler for a connection to the OpenAI Realtime API.
6267
// It reads messages from the server in a standalone goroutine and calls the registered handlers.
6368
// It is the responsibility of the caller to call Start and Stop.

conn_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type mockWebSocketConn struct {
2222
writeMessageFunc func(ctx context.Context, messageType openairt.MessageType, data []byte) error
2323
closeFunc func() error
2424
responseFunc func() *http.Response
25+
pingFunc func(ctx context.Context) error
2526
}
2627

2728
func (m *mockWebSocketConn) ReadMessage(ctx context.Context) (openairt.MessageType, []byte, error) {
@@ -40,6 +41,10 @@ func (m *mockWebSocketConn) Response() *http.Response {
4041
return m.responseFunc()
4142
}
4243

44+
func (m *mockWebSocketConn) Ping(ctx context.Context) error {
45+
return m.pingFunc(ctx)
46+
}
47+
4348
func TestConnect(t *testing.T) {
4449
token := "mock-token"
4550
model := "test-model"

contrib/ws-gorilla/go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.19
55
// replace github.com/WqyJh/go-openai-realtime => ../../
66

77
require (
8-
github.com/WqyJh/go-openai-realtime v0.2.0-beta.2
8+
github.com/WqyJh/go-openai-realtime v0.3.5-0.20250208091501-af3079f3fb2b
99
github.com/gorilla/websocket v1.5.3
1010
github.com/stretchr/testify v1.9.0
1111
)
@@ -14,6 +14,5 @@ require (
1414
github.com/coder/websocket v1.8.12 // indirect
1515
github.com/davecgh/go-spew v1.1.1 // indirect
1616
github.com/pmezard/go-difflib v1.0.0 // indirect
17-
github.com/sashabaranov/go-openai v1.32.0 // indirect
1817
gopkg.in/yaml.v3 v3.0.1 // indirect
1918
)

contrib/ws-gorilla/go.sum

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
github.com/WqyJh/go-openai-realtime v0.2.0-beta.2 h1:4xD7O/IN5dQD2gKsiPzP1Prdu5HtCy25CChXep9kaIs=
2-
github.com/WqyJh/go-openai-realtime v0.2.0-beta.2/go.mod h1:nmUYODacQuObuh0DFSEIDfJM9L4ZFDRU/OEGYMryt60=
1+
github.com/WqyJh/go-openai-realtime v0.3.5-0.20250208091501-af3079f3fb2b h1:8teuz/JaWkMaqBrlIKF86EhHi0ajbJrm+shD1IXCvK8=
2+
github.com/WqyJh/go-openai-realtime v0.3.5-0.20250208091501-af3079f3fb2b/go.mod h1:nmUYODacQuObuh0DFSEIDfJM9L4ZFDRU/OEGYMryt60=
33
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
44
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
55
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -9,7 +9,6 @@ github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
99
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1010
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1111
github.com/sashabaranov/go-openai v1.32.0 h1:Yk3iE9moX3RBXxrof3OBtUBrE7qZR0zF9ebsoO4zVzI=
12-
github.com/sashabaranov/go-openai v1.32.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
1312
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
1413
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
1514
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

contrib/ws-gorilla/ws_gorilla.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,14 @@ func (c *WebSocketConn) Close() error {
118118
func (c *WebSocketConn) Response() *http.Response {
119119
return c.resp
120120
}
121+
122+
// Ping sends a ping message to the WebSocket connection.
123+
// It won't be blocked until the pong message is received.
124+
func (c *WebSocketConn) Ping(ctx context.Context) error {
125+
deadline, ok := ctx.Deadline()
126+
if ok {
127+
_ = c.conn.SetWriteDeadline(deadline)
128+
}
129+
130+
return c.conn.WriteControl(websocket.PingMessage, []byte{}, deadline)
131+
}

examples/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/WqyJh/go-openai-realtime/examples
33
go 1.19
44

55
require (
6-
github.com/WqyJh/go-openai-realtime v0.3.0-alpha
6+
github.com/WqyJh/go-openai-realtime v0.3.5-0.20250208091501-af3079f3fb2b
77
github.com/faiface/beep v1.1.0
88
github.com/gordonklaus/portaudio v0.0.0-20230709114228-aafa478834f5
99
github.com/sashabaranov/go-openai v1.32.0

examples/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
2-
github.com/WqyJh/go-openai-realtime v0.3.0-alpha h1:2IDh9xm3VLAXnmOtbOhv2/ytMceJYgj7Cw0e1TbqBpY=
3-
github.com/WqyJh/go-openai-realtime v0.3.0-alpha/go.mod h1:nmUYODacQuObuh0DFSEIDfJM9L4ZFDRU/OEGYMryt60=
2+
github.com/WqyJh/go-openai-realtime v0.3.5-0.20250208091501-af3079f3fb2b h1:8teuz/JaWkMaqBrlIKF86EhHi0ajbJrm+shD1IXCvK8=
3+
github.com/WqyJh/go-openai-realtime v0.3.5-0.20250208091501-af3079f3fb2b/go.mod h1:nmUYODacQuObuh0DFSEIDfJM9L4ZFDRU/OEGYMryt60=
44
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
55
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
66
github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=

examples/text-only/main.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"fmt"
77
"log"
88
"os"
9+
"sync"
10+
"time"
911

1012
openairt "github.com/WqyJh/go-openai-realtime"
1113
)
@@ -19,6 +21,8 @@ func main() {
1921
log.Fatal(err)
2022
}
2123

24+
var sendLock sync.Mutex
25+
2226
// Teletype response
2327
responseDeltaHandler := func(ctx context.Context, event openairt.ServerEvent) {
2428
switch event.ServerEventType() {
@@ -48,6 +52,24 @@ func main() {
4852
log.Fatal(err)
4953
}
5054

55+
go func() {
56+
for {
57+
select {
58+
case <-ctx.Done():
59+
return
60+
case <-time.After(30 * time.Second):
61+
sendLock.Lock()
62+
err := conn.Ping(ctx)
63+
sendLock.Unlock()
64+
if err != nil {
65+
log.Printf("ping error: %v", err)
66+
} else {
67+
log.Printf("ping success")
68+
}
69+
}
70+
}
71+
}()
72+
5173
fmt.Println("Conversation")
5274
fmt.Println("---------------------")
5375
fmt.Print("> ")
@@ -56,6 +78,7 @@ func main() {
5678
if s.Text() == "exit" || s.Text() == "quit" {
5779
break
5880
}
81+
sendLock.Lock()
5982
conn.SendMessage(ctx, &openairt.ConversationItemCreateEvent{
6083
Item: openairt.MessageItem{
6184
ID: openairt.GenerateID("msg_", 10),
@@ -76,6 +99,7 @@ func main() {
7699
MaxOutputTokens: 4000,
77100
},
78101
})
102+
sendLock.Unlock()
79103
}
80104
conn.Close()
81105
err = <-connHandler.Err()

ws.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ type WebSocketConn interface {
5454
// Response returns the *http.Response of the WebSocket connection.
5555
// Commonly used to get response headers.
5656
Response() *http.Response
57+
58+
// Ping sends a ping message to the WebSocket connection.
59+
Ping(ctx context.Context) error
5760
}
5861

5962
// WebSocketDialer is a WebSocket connection dialer abstraction.

ws_coder.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,9 @@ func (c *CoderWebSocketConn) Close() error {
128128
func (c *CoderWebSocketConn) Response() *http.Response {
129129
return c.resp
130130
}
131+
132+
// Ping sends a ping message to the WebSocket connection.
133+
// It would be blocked until the pong message is received or the ctx is done.
134+
func (c *CoderWebSocketConn) Ping(ctx context.Context) error {
135+
return c.conn.Ping(ctx)
136+
}

0 commit comments

Comments
 (0)