websocket 为什么是按顺序执行的?

2020-07-10 12:38:30 +08:00
 wunonglin

我用的是 echo 里面的 gorilla websocket 示例

https://echo.labstack.com/cookbook/websocket

我原本的后台是 node 写的,node 上没事,但是为什么 go 这边是按顺序执行的而不是同时执行?

4857 次点击
所在节点    Go 编程语言
30 条回复
knva
2020-07-10 14:51:05 +08:00
没做过,但是我觉得开个协程不就得了
binux
2020-07-10 14:56:37 +08:00
执行什么?
w99w
2020-07-10 14:59:41 +08:00
你的请求是同时嘛?
wunonglin
2020-07-10 14:59:57 +08:00
@binux #2 执行了个 http 请求,我页面是 6 个任务同时发送的,但是后台是一个接一个执行,而不是同时执行 6 个任务
wunonglin
2020-07-10 15:00:40 +08:00
@w99w #3 对,页面请求是同时发出 6 个请求的,看时间戳就知道了
takemeaway
2020-07-10 15:02:04 +08:00
如果没有开协程和多线程,那么本身就是按顺序执行的。
wunonglin
2020-07-10 15:07:55 +08:00
@takemeaway #6 对,我是想过应该是这个问题。刚接触 go 还不太了解,没搜到有关 websocket 的教程或者例子,找到的那些都是聊天室的例子,但我这个只是 1v1 的
BingoXuan
2020-07-10 15:15:46 +08:00
因为你函数写的是同步代码,你需要开协程去处理,并通过 chan 来收发结果。

起码把代码发一下,不然 v 友都不知道你做了什么暗箱操作
whileFalse
2020-07-10 15:24:00 +08:00
LZ 的 Node 环境是不是开了多线程了。
Node 本身是异步单线程的,加上多线程那就是乱序了……
wunonglin
2020-07-10 15:24:19 +08:00
@BingoXuan #8 代码我 append 了,貌似没有在线运行 go 的代码托管网站
wunonglin
2020-07-10 15:27:59 +08:00
@whileFalse #9 单线,异步的。转 go 之后不知道 go 这边要怎么写
keepeye
2020-07-10 15:30:48 +08:00
第一张图每次 send 间隔好几毫秒啊 同时请求??
wunonglin
2020-07-10 15:38:15 +08:00
@keepeye #12

也不能说死磕”同时“这个字眼,你发到后台去,按我理解的话它肯定是接收到一个就去执行一个,但是 go 这边像是被缓存住了,是一个执行完成后再去执行,而不是“接收到一个就去执行一个”。应该就是像#6 说的那样
keepeye
2020-07-10 15:43:54 +08:00
@wunonglin 一个长连接本来就是顺序接收消息的啊,不知道 node 是怎么处理的,可能收到一条消息都生成 async task 类似 goroutine 吧
xylophone21
2020-07-10 15:44:04 +08:00
1. 看一下你给的链接里的 demo,https://github.com/labstack/echox/blob/master/cookbook/websocket/gorilla/server.go 。Subscribe 里 readLoop 不应该新开 go 程,直接卡在这里,直到 ws 断开。因为 Subscribe 是 HTTP Server 调的,你返回了,它就会认为这个连接已经结束了,虽然不一定会马上关(keep-alive),但必要的时候会断开。

2. 作为一个 HTTP Server,Subscribe 应该是在不同的 go 程里被调用的,不然就就成了单协程了,你可以打印出来试一下
wunonglin
2020-07-10 15:47:26 +08:00
@keepeye #14 我是用 nest.js ,async 、await
wunonglin
2020-07-10 15:52:11 +08:00
@xylophone21 #15

上面 append 的是我测试的代码,在跑着的代码是这样的 https://play.golang.org/p/4_Y4wUE3iNy,跟例子一样的,然后东搞搞西搞搞就成了上面那样
xylophone21
2020-07-10 16:11:37 +08:00
@wunonglin
1.是否你的每个 for 在不同的 go 程,打印出来看看
2. 加延迟,晚点发
keepeye
2020-07-10 16:12:29 +08:00
@wunonglin nestjs 里面改成同步响应就和 go 一样了,或者 go 里面读到 body 的时候新建一个 goroutine 处理这样也就和 nestjs 里的异步响应效果一样。你用 nodejs 之所以习惯了异步处理是因为程序是单线程的,同步可能会长时间阻塞其他的请求,但在 go 里面,每个连接本身就在一个 goroutine 里,放心用同步的方式处理消息就是了,还能避免乱序问题
wunonglin
2020-07-10 16:15:59 +08:00
@keepeye #19 乱序是什么?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/688833

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX