lxzan / gws

simple, fast, reliable websocket server & client, supports running over tcp/kcp/unix domain socket. keywords: ws, proxy, chat, go, golang...
https://pkg.go.dev/github.com/lxzan/gws
Apache License 2.0
1.34k stars 84 forks source link

能不能把 `gws.Conn.isClosed()`方法改成可公开访问的? #57

Closed davidxifeng closed 10 months ago

davidxifeng commented 10 months ago

首先谢谢大佬的作品.

github.com/lxzan/gws@v1.6.12/conn.go:84

我想把conn 保存到别的地方, 想在那里调用发送之前先判断一下是否已经ws是否已经断开.

但发现这个接口没有公开, 请问是否可以公开给用户使用? 会不会有什么潜在的问题?

如果不公开的话,推荐的做法是什么? 另外在on open on close回调中处理对应的连接状态,自行维护?

lxzan commented 10 months ago

调用之前不需要判断是否连接关闭, gws内部有判断. 你可以假设连接都是活跃的, onclose之后剔除断开的连接.

我看别的websocket项目都没有导出IsActive/IsClose方法, 也就设为私有方法了.

davidxifeng commented 10 months ago

ok,这样也可以. 就是在on close中处理好了,谢谢回复.

lxzan commented 10 months ago

非必要不导出, 一旦导出就不能随意修改了, 要尽量确保API向下兼容.

guonaihong commented 10 months ago

导出IsClose没必要。

  1. 如果要确保api准确性,需要要存活探测。
  2. 如果用lazy 的思路做,和WriteMessage探测失败没有区别。

感知失败的一般做法

  1. OnClose
  2. WriteMessage发现失败 OnMessage为了保活链接,超时时间一般设置得比较长,所以OnClose只是发现错误的一种可能性,还一种是看下WriteMessage的返回err,由于tcp可靠但不绝对可靠,写入一定要加超时时间,哪怕在内网由于交换机的卡死,不加超时,也有可能tcp坏了,感知不到。
davidxifeng commented 10 months ago

学习了,谢谢大佬! 😃

davidxifeng commented 10 months ago

请教一下二位, 我粗看了一下代码,但有点不敢确定.

如果WriteMessage失败后, emitError会调用底层的net close,注释中说close会导致read write立即返回错误.

是不是 只要WriteMessage失败, 不管当前状态如何,ReadLoop那都会正常结束读消息的循环, 然后OnClose回调都会执行啊?

如果我只在OnClose中执行清理工作的话, WriteMessage时失败的错误值不用处理, 也可以保证OnClose会执行啊?

~还是说我需要在发现失败后主动调一下OnClose?~


谢谢回答, gws的API设计的真好, 👍 ❤️

lxzan commented 10 months ago

是不是 只要WriteMessage失败, 不管当前状态如何,ReadLoop那都会正常结束读消息的循环, 然后OnClose回调都会执行啊?

是的

gws.Conn导出方法返回的错误都是可忽略的, 内部有错误处理, 最终回调OnClose.

IO Error => emitError => OnClose

这个过程中会自动关闭连接, 退出ReadLoop循环.