go func() {
defer func() {
o.msg.PushLock_tag(`exit`, nil)
- o.msg.ClearAll()
o.l.Lock()
o.close = true
o.l.Unlock()
for {
if err := c.SetReadDeadline(time.Now().Add(time.Duration(o.RTOMs * int(time.Millisecond)))); err != nil {
o.error(err)
- o.msg.ClearAll()
return
}
msg_type, message, err := c.ReadMessage()
o.Func_normal_close()
case websocket.CloseAbnormalClosure:
o.Func_abort_close()
+ o.error(err)
default:
+ o.error(err)
}
+ } else {
o.error(err)
}
return
}
if err := c.SetWriteDeadline(time.Now().Add(time.Duration(o.WTOMs * int(time.Millisecond)))); err != nil {
o.error(err)
- o.msg.ClearAll()
return true
}
if err := c.WriteMessage(wm.Type, wm.Msg); err != nil {
o.error(err)
- o.msg.ClearAll()
return true
}
if wm.Type == websocket.PingMessage {
// close
o.msg.Pull_tag_only(`close`, func(_ *WsMsg) (disable bool) {
+ if err := c.SetWriteDeadline(time.Now().Add(time.Duration(o.WTOMs * int(time.Millisecond)))); err != nil {
+ o.error(err)
+ }
if err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, o.Msg_normal_close)); err != nil {
o.error(err)
- o.msg.ClearAll()
}
return true
})
func (o *Client) Isclose() (isclose bool) {
o.l.RLock()
- isclose = o.close
- o.l.RUnlock()
- return
+ defer o.l.RUnlock()
+ return o.close
}
func (o *Client) Error() (e error) {
o.l.RLock()
- e = o.err
- o.l.RUnlock()
- return
+ defer o.l.RUnlock()
+ return o.err
}
func (o *Client) error(e error) {
o.l.Lock()
+ defer o.l.Unlock()
o.err = errors.Join(o.err, e)
- o.l.Unlock()
}
import (
"context"
"net/http"
+ "strings"
"testing"
"time"
time.Sleep(time.Second)
- c, e := New_client(&Client{
- Url: "ws://127.0.0.1:10888/ws",
- Func_normal_close: func() {
- t.Log("close")
- },
- TO: 5000,
- })
- if e != nil {
- t.Fatal(e)
- }
+ {
+ c, e := New_client(&Client{
+ Url: "ws://127.0.0.1:10888/ws",
+ Func_normal_close: func() {
+ t.Log("close")
+ },
+ TO: 1000,
+ WTOMs: 1000,
+ })
+ if e != nil {
+ t.Fatal(e)
+ }
- ws, e := c.Handle()
- if e != nil {
- t.Fatal(e)
- }
+ ws, e := c.Handle()
+ if e != nil {
+ t.Fatal(e)
+ }
- ws.Pull_tag_only(`rec`, func(wm *WsMsg) (disable bool) {
- if string(wm.Msg) != "test" {
+ ws.Pull_tag_only(`rec`, func(wm *WsMsg) (disable bool) {
+ if string(wm.Msg) != "test" {
+ t.Fatal()
+ }
+ return false
+ })
+ ws.PushLock_tag(`send`, &WsMsg{
+ Msg: []byte("test"),
+ })
+
+ go func() {
+ time.Sleep(time.Second * 2)
+ t.Log("call close")
+ c.Close()
+ t.Log("call close done")
+ }()
+
+ {
+ cancel, c := ws.Pull_tag_chan(`exit`, 1, context.Background())
+ <-c
+ cancel()
+ t.Log("exit")
+ }
+
+ if !strings.Contains(c.Error().Error(), `i/o`) {
t.Fatal()
}
- return false
- })
- ws.PushLock_tag(`send`, &WsMsg{
- Msg: []byte("test"),
- })
- go func() {
time.Sleep(time.Second)
- t.Log("call close")
- c.Close()
- t.Log("call close done")
- }()
-
+ }
{
- cancel, c := ws.Pull_tag_chan(`exit`, 1, context.Background())
- <-c
- cancel()
- t.Log("exit")
+ c, e := New_client(&Client{
+ Url: "ws://127.0.0.1:10888/ws",
+ Func_normal_close: func() {
+ t.Log("close")
+ },
+ TO: 2000,
+ })
+ if e != nil {
+ t.Fatal(e)
+ }
+
+ ws, e := c.Handle()
+ if e != nil {
+ t.Fatal(e)
+ }
+
+ ws.Pull_tag_only(`rec`, func(wm *WsMsg) (disable bool) {
+ if string(wm.Msg) != "test" {
+ t.Fatal()
+ }
+ return false
+ })
+ ws.PushLock_tag(`send`, &WsMsg{
+ Msg: []byte("test"),
+ })
+
+ go func() {
+ time.Sleep(time.Second)
+ t.Log("call close")
+ c.Close()
+ t.Log("call close done")
+ }()
+
+ {
+ cancel, c := ws.Pull_tag_chan(`exit`, 1, context.Background())
+ <-c
+ cancel()
+ t.Log("exit")
+ }
+
+ if c.Error() != nil {
+ t.Fatal(c.Error())
+ }
+
+ time.Sleep(time.Second)
}
- time.Sleep(time.Second)
}