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.36k stars 87 forks source link

关于处理 continue 结束包的疑问 #38

Closed shaovie closed 1 year ago

shaovie commented 1 year ago

https://github.com/lxzan/gws/blob/master/reader.go#L111C6-L111C6 if fin && opcode != OpcodeContinuation { return c.emitMessage(&Message{index: index, Opcode: opcode, Data: bytes.NewBuffer(p)}, compressed) } 这里不包含 continue 结束包吗

lxzan commented 1 year ago

是的,这里是处理不分片的消息

shaovie commented 1 year ago

但是分片消息结束的标志 不就是 fin && opcode != OpcodeContinuation 并且 c.continuationFrame.initialized == true 吗? 你这样提前判断,就会漏掉最后一个分片完成消息的处理了

lxzan commented 1 year ago

分片消息结束的标志是 fin && opcode == OpcodeContinuation,分片消息开始的标志是 !fin && opcode == OpcodeText|OpcodeBinary.

shaovie commented 1 year ago

哦,我看的文章 写错了 https://zhuanlan.zhihu.com/p/407711596 这里边说的是: 对于最后一个分片的消息, 其 FIN 字段为 1, 并且 Opcode 字段的值为 0x1

我又查了一下,最后一片 opcode=0

shaovie commented 1 year ago

TMD https://zhuanlan.zhihu.com/p/605823149 这个文章 也说的最后一片 opcode=1,妈蛋,要查RFC吗

lxzan commented 1 year ago

WS有完善的测试工具:https://lxzan.github.io/gws/reports/servers/

shaovie commented 1 year ago

我查了rfc ,确实是跟你说的规则一样,最后片 fin=1 opcode=0 https://www.rfc-editor.org/rfc/rfc6455.html#section-5.4

lxzan commented 1 year ago

如果只是为了性能压测,你不需要做完整的实现

shaovie commented 1 year ago

完成 差不多了,https://github.com/shaovie/goev/blob/main/example/websocket.go 哈哈

lxzan commented 1 year ago

这么快👍🏻

shaovie commented 1 year ago

https://github.com/lxzan/gws/blob/master/protocol.go#L137

给长度赋值,为什么要用 += ?

lxzan commented 1 year ago

https://github.com/lxzan/gws/blob/master/protocol.go#L137

给长度赋值,为什么要用 += ?

看RFC帧头结构,这里加和或是等效的

shaovie commented 1 year ago

我意思是 为什么不是直接 赋值 = ,为什么要累加

lxzan commented 1 year ago

先给 Payload len 赋值后设置 MASK 也是可以的, 加法不用考虑顺序

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     |     Extended payload length continued, if payload len == 127  |
     + - - - - - - - - - - - - - - - +-------------------------------+
     |                               |Masking-key, if MASK set to 1  |
     +-------------------------------+-------------------------------+
     | Masking-key (continued)       |          Payload Data         |
     +-------------------------------- - - - - - - - - - - - - - - - +
     :                     Payload Data continued ...                :
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     |                     Payload Data continued ...                |
     +---------------------------------------------------------------+
shaovie commented 1 year ago

WS有完善的测试工具:https://lxzan.github.io/gws/reports/servers/

这个站为啥打不开?我也翻墙了

lxzan commented 1 year ago

WS有完善的测试工具:https://lxzan.github.io/gws/reports/servers/

这个站为啥打不开?我也翻墙了

检查代理配置 / 换个节点试试

shaovie commented 1 year ago

不行,台湾 东京 香港都不行,测试卡在write frame header了,

image

测试站 提示invalide frame header

shaovie commented 1 year ago

我看测试站,一般都是 上来就先发一个close frame 是吧

lxzan commented 1 year ago

不行,台湾 东京 香港都不行,测试卡在write frame header了,

image

测试站 提示invalide frame header

你的帧头构造得有问题

lxzan commented 1 year ago

我看测试站,一般都是 上来就先发一个close frame 是吧

断点看

shaovie commented 1 year ago

没看出来哪里有问题呢,就两个字节

lxzan commented 1 year ago

没看出来哪里有问题呢,就两个字节

打印hex字符串,和gws对比,完全一致的话就去网络库找问题

shaovie commented 1 year ago

测试流程没问题吧,对方发个close过来,我把close信息原样返回去

lxzan commented 1 year ago

测试流程没问题吧,对方发个close过来,我把close信息原样返回去

回1000,nil

shaovie commented 1 year ago

我有个疑问,为什么switch成功后,对方先发一个 closeframe code=1002 err="WebSocket Protocol” 过来?

lxzan commented 1 year ago

我有个疑问,为什么switch成功后,对方先发一个 closeframe code=1002 err="WebSocket Protocol” 过来?

协议错误,原因很多,你去gws里面搜一下哪些地方返回了这个

shaovie commented 1 year ago

我还有个疑问 https://github.com/lxzan/gws/blob/master/protocol.go#L204

mask 是固定 10:14 吗?不对吧,应该是在payloadlen 后边的4个字节吧

lxzan commented 1 year ago

我还有个疑问 https://github.com/lxzan/gws/blob/master/protocol.go#L204

mask 是固定 10:14 吗?不对吧,应该是在payloadlen 后边的4个字节吧

我只是用这样方式解析,构造不是这样的。懒得算偏移量了

shaovie commented 1 year ago

这样不会有问题?当payload=uint16的时候 解出来的mask不对吧

lxzan commented 1 year ago

这样不会有问题?当payload=uint16的时候 解出来的mask不对吧

有问题autobahn早就测出来了

shaovie commented 1 year ago

逻辑不通吧

shaovie commented 1 year ago

我有个疑问,为什么switch成功后,对方先发一个 closeframe code=1002 err="WebSocket Protocol” 过来?

我知道了,应该是我的switch 回应有问题,所以它直接close了

铁子帮我喵一眼,有没有问题,看半天没查出问题

image
lxzan commented 1 year ago

我有个疑问,为什么switch成功后,对方先发一个 closeframe code=1002 err="WebSocket Protocol” 过来?

我知道了,应该是我的switch 回应有问题,所以它直接close了

铁子帮我喵一眼,有没有问题,看半天没查出问题

image

你的压缩扩展已经写好了? response header似乎没这么多

shaovie commented 1 year ago

没啊,还没走到那一步呢,我不返回Extensions 对端也会close 1002

lxzan commented 1 year ago

The handshake from the server looks as follows:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
shaovie commented 1 year ago

Sec-WebSocket-Version: 13 这个得有

lxzan commented 1 year ago

Sec-WebSocket-Version: 13 这个得有

好好看RFC6455

shaovie commented 1 year ago

去掉这个 对端直接报 1002 Invalid reserv

lxzan commented 1 year ago

chrome连接gws server:

shaovie commented 1 year ago

en,确实不需要,难道是accept 算错了?是抄你的代码啊,哈哈

shaovie commented 1 year ago

搞不定了,先放一放

shaovie commented 1 year ago

铁子,帮我看看呗 https://github.com/shaovie/goev/blob/main/example/websocket.go

shaovie commented 1 year ago

https://gitee.com/casterlee/websocket/blob/master/websocket.go 这个我看了,现在问题就卡在connectHandshake, connectHandshake 这部分我实在没看出来哪里有问题,为什么测试网站 给我close了

lxzan commented 1 year ago

chrome的提示很明显了

image
lxzan commented 1 year ago

这个地方应该是resp吧, 改完连接就不会自动断开了

image
shaovie commented 1 year ago

NB,echo我测通过了

lxzan commented 1 year ago

通过观察chrome给的信息我怀疑你写入了unexpected contents

shaovie commented 1 year ago

除了tcpkali 还有别的工具可以压测吗,我服务器上源码安装tcpkali没成功,编译失败,可能系统太新了,

lxzan commented 1 year ago

删掉这行就能编译了 https://github.com/satori-com/tcpkali/blob/3c3175e417366c7ccafba56454903690fede501a/src/tcpkali_syslimits.c#L34

shaovie commented 1 year ago

搞定了,给个echo测试的tcpkaili的参数呗