-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bugs For arpc.js #16
Comments
是否有遇到您疑惑的点相关的bug,如果遇到,请提供下能够复现的完整示例代码我这边排查下。 我先对于您疑惑的几个点做一下解释:
这是由于 server 端默认是 批次发送 的,默认提供的websocket扩展是基于gorilla/websocket.Conn进行封装实现了 net.Conn 的接口,websocket.Conn 只是作为 net.Conn 接口,当发生批次发送时,server会把多个 arpc Message 合并成一段 buffer 执行 websocket.Conn 封装的 Write: 所以,虽然 websocket 本身不需要处理所谓的
上面已经讲到,一个 websocket Message 可能包含多个 arpc Message,并且本身封装的 Write 也是调用 WriteMessage,所以可以保证一个 websocket Message 中一个或者多个 arpc Message 的完整性,不需要担心 js client 解析时遇到半个 arpc Message 的问题,所以要么 offset 已经大于 websocket Message 长度结束循环,要么 headerArr 就正常拿到完整包头: |
上面我写的部分代码就是例子了…… 可能比较麻烦,我重写了一个 Demo 打包发给您,在写的过程中我发现了另一个问题,就是如果使用这种订阅模式,另一个客户端如果不是 web 端,而是 server 端的话,会出现 timeout 的情况,在代码里我也一并打包给您了。 单纯运行 server 的程序,然后打开网页端就是我说的上述没有正确分段导致 websocket Message 截断的问题; 代码均在 main.go 中,要编译 client 程序,将 main() 里面的 server [部分代码注释,其余部分解开注释即可。 |
你例子中的server用的是websocket,你指的超时应该是说go client的超时吧?因为你的go client用的是tcp协议,tcp连到go的 websocket上,websocket msg解析都没通。 另外代码中还有一些问题,比如:
context.Client.Handler.HandleDisconnected(func(clientWhichDisconnected *arpc.Client) {
//remove from BroadcastClients
idx := indexOfClient(clientWhichDisconnected,BroadcastClients)
if idx >= 0 {
if length := len(BroadcastClients); length != 1 {
BroadcastClients[idx] = BroadcastClients[length - 1]
BroadcastClients = BroadcastClients[:length - 1]
}else {
BroadcastClients = BroadcastClients[:0]
}
}
}); 而是应该为 server 的Handler 统一设置: server.Handler.HandleDisconnected(...) |
如果想既服务 ws 又服务 tcp,可以开两个端口分别处理不同的协议,如: arpc.DefaultHandler.Handle("/auth", func(context *arpc.Context) {...}
arpc.DefaultHandler.HandleDisconnected(...)
ln, _ := websocket.Listen("ws addr", nil)
http.HandleFunc("/ws", ln.(*websocket.Listener).Handler)
wsServer := arpc.NewServer()
go wsServer.Serve(ln)
tcpServer := arpc.NewServer()
tcpServer.Run("tcp addr") 当然你也可以自己实现一个 listener,封装一层,根据Accept后根据读到的前几个字节判断是否为http upgrade ws,是则转给 ws server 否则转给 tcp server,这样可以实现共用一个端口来服务两个不同的协议,但是会有性能损失和不必要的复杂度。 当然,你也可以使用 websocket 作为 go client 的协议,但不如直接用tcp性能好。 |
确实是,看了下代码,计算 body length 时多写了个 & 0xFF,导致只计算了第一个字节,稍等我修复更新上去。 感谢反馈! |
已修复: 0f639ef 请尝试最新版本的 js client |
赞👍 |
您好,请问一下,有关 websocket 的消息截断的问题,在 onMessage 函数下,通过 offset 去循环处理一段消息,这里使用 offset 的原因是什么?
arpc/extension/jsclient/arpc.js
Lines 179 to 188 in 9ff9485
我在使用的时候,发现 bodyLen 的长度计算不正确,例如我从服务器推送一条 Notify 的消息,在这里断点,得到的 event.data.byteLength 长度是 645,然而通过 bodyLen 计算出来的结果是 119,即使这是在 while 循环中,offset 会在下一次循环开始前偏移,但是消息已经在第一次循环里就发送给 handle 了
arpc/extension/jsclient/arpc.js
Lines 211 to 214 in 9ff9485
还有另一个问题是,第二次循环中,header 的内容并不存在,计算的 method 或者其他信息都是原来消息体的一部分信息,即使想要组装数据,似乎也没法完成。
arpc/extension/jsclient/arpc.js
Lines 190 to 192 in 9ff9485
以下是我使用的部分代码:
The text was updated successfully, but these errors were encountered: