@@ -14,8 +14,7 @@ import (
14
14
)
15
15
16
16
// Empty struct for logger initialization
17
- type Empty struct {
18
- }
17
+ type Empty struct {}
19
18
20
19
// Initialize logger
21
20
var logger = logging .GetLogger (reflect .TypeOf (Empty {}).PkgPath ()).SetLevel (logging .OFF )
@@ -46,9 +45,11 @@ type Socket struct {
46
45
OnPongReceived func (data string , socket Socket )
47
46
IsConnected bool
48
47
Timeout time.Duration
49
- sendMu * sync.Mutex // Mutex to prevent concurrent writes
50
- receiveMu * sync.Mutex // Mutex to prevent concurrent reads
51
- connStateMu sync.Mutex // Mutex to protect connection state
48
+ sendMu sync.Mutex // Mutex to prevent concurrent writes
49
+ receiveMu sync.Mutex // Mutex to prevent concurrent reads
50
+ connStateMu sync.Mutex // Mutex to protect connection state
51
+ closeChan chan struct {} // Channel to signal closing
52
+ closeWg sync.WaitGroup // WaitGroup to wait for goroutines
52
53
}
53
54
54
55
// Connection options structure
@@ -61,6 +62,7 @@ type ConnectionOptions struct {
61
62
62
63
// Reconnection options (to be implemented)
63
64
type ReconnectionOptions struct {
65
+ // Fields for reconnection options
64
66
}
65
67
66
68
// Create a new Socket instance
@@ -74,8 +76,8 @@ func New(url string) Socket {
74
76
},
75
77
WebsocketDialer : & websocket.Dialer {},
76
78
Timeout : 0 ,
77
- sendMu : & sync. Mutex {} ,
78
- receiveMu : & sync. Mutex {},
79
+ closeChan : make ( chan struct {}) ,
80
+ // Other fields are zero-initialized
79
81
}
80
82
}
81
83
@@ -93,6 +95,7 @@ func (socket *Socket) Connect() {
93
95
var resp * http.Response
94
96
socket .setConnectionOptions ()
95
97
98
+ // Dial the websocket connection
96
99
socket .Conn , resp , err = socket .WebsocketDialer .Dial (socket .Url , socket .RequestHeader )
97
100
98
101
if err != nil {
@@ -156,37 +159,48 @@ func (socket *Socket) Connect() {
156
159
return result
157
160
})
158
161
162
+ // Initialize close channel and WaitGroup
163
+ socket .closeChan = make (chan struct {})
164
+ socket .closeWg .Add (1 )
165
+
159
166
// Start reading messages
160
167
go func () {
168
+ defer socket .closeWg .Done ()
161
169
for {
162
- socket .receiveMu .Lock ()
163
- if socket .Timeout != 0 {
164
- socket .Conn .SetReadDeadline (time .Now ().Add (socket .Timeout ))
165
- }
166
- messageType , message , err := socket .Conn .ReadMessage ()
167
- socket .receiveMu .Unlock ()
168
- if err != nil {
169
- logger .Error .Println ("read:" , err )
170
- socket .connStateMu .Lock ()
171
- socket .IsConnected = false
172
- onDisconnected := socket .OnDisconnected
173
- socket .connStateMu .Unlock ()
174
-
175
- if onDisconnected != nil {
176
- onDisconnected (err , * socket )
177
- }
170
+ select {
171
+ case <- socket .closeChan :
172
+ // Received close signal, exiting goroutine
178
173
return
179
- }
180
- logger .Info .Printf ("recv: %s" , message )
181
-
182
- switch messageType {
183
- case websocket .TextMessage :
184
- if socket .OnTextMessage != nil {
185
- socket .OnTextMessage (string (message ), * socket )
174
+ default :
175
+ socket .receiveMu .Lock ()
176
+ if socket .Timeout != 0 {
177
+ socket .Conn .SetReadDeadline (time .Now ().Add (socket .Timeout ))
178
+ }
179
+ messageType , message , err := socket .Conn .ReadMessage ()
180
+ socket .receiveMu .Unlock ()
181
+ if err != nil {
182
+ logger .Error .Println ("read:" , err )
183
+ socket .connStateMu .Lock ()
184
+ socket .IsConnected = false
185
+ onDisconnected := socket .OnDisconnected
186
+ socket .connStateMu .Unlock ()
187
+
188
+ if onDisconnected != nil {
189
+ onDisconnected (err , * socket )
190
+ }
191
+ return
186
192
}
187
- case websocket .BinaryMessage :
188
- if socket .OnBinaryMessage != nil {
189
- socket .OnBinaryMessage (message , * socket )
193
+ logger .Info .Printf ("recv: %s" , message )
194
+
195
+ switch messageType {
196
+ case websocket .TextMessage :
197
+ if socket .OnTextMessage != nil {
198
+ socket .OnTextMessage (string (message ), * socket )
199
+ }
200
+ case websocket .BinaryMessage :
201
+ if socket .OnBinaryMessage != nil {
202
+ socket .OnBinaryMessage (message , * socket )
203
+ }
190
204
}
191
205
}
192
206
}
@@ -227,9 +241,15 @@ func (socket *Socket) Close() {
227
241
logger .Error .Println ("write close:" , err )
228
242
}
229
243
230
- // Close the connection
244
+ // Close the websocket connection
231
245
socket .Conn .Close ()
232
246
247
+ // Signal the goroutine to exit
248
+ close (socket .closeChan )
249
+
250
+ // Wait for the goroutine to finish
251
+ socket .closeWg .Wait ()
252
+
233
253
// Protect access to IsConnected and OnDisconnected
234
254
socket .connStateMu .Lock ()
235
255
socket .IsConnected = false
0 commit comments