GithubHelp home page GithubHelp logo

Bugs For arpc.js about arpc HOT 8 CLOSED

spxvszero avatar spxvszero commented on June 26, 2024
Bugs For arpc.js

from arpc.

Comments (8)

spxvszero avatar spxvszero commented on June 26, 2024 1

感谢您的回复

JS Client 是能收到消息,但是被截断了,以下是浏览器的输出:

image

实际 Server 端发送的消息是:

image

也非常感谢您的建议

  1. 没有加锁是我的疏忽,由于写的是 Demo,没有考虑太多了。
  2. Server 的 HandleDisconnected 我原以为是 Server 端终止的时候会调用的回调,感谢您的建议。
  3. 我的确是想着同一个端口处理 ws 和 rpc,也感谢您的建议。

from arpc.

lesismal avatar lesismal commented on June 26, 2024

是否有遇到您疑惑的点相关的bug,如果遇到,请提供下能够复现的完整示例代码我这边排查下。

我先对于您疑惑的几个点做一下解释:

您好,请问一下,有关 websocket 的消息截断的问题,在 onMessage 函数下,通过 offset 去循环处理一段消息,这里使用 offset 的原因是什么?
我在使用的时候,发现 bodyLen 的长度计算不正确,例如我从服务器推送一条 Notify 的消息,在这里断点,得到的 event.data.byteLength 长度是 645,然而通过 bodyLen 计算出来的结果是 119,即使这是在 while 循环中,offset 会在下一次循环开始前偏移,但是消息已经在第一次循环里就发送给 handle 了

这是由于 server 端默认是 批次发送 的,默认提供的websocket扩展是基于gorilla/websocket.Conn进行封装实现了 net.Conn 的接口,websocket.Conn 只是作为 net.Conn 接口,当发生批次发送时,server会把多个 arpc Message 合并成一段 buffer 执行 websocket.Conn 封装的 Write:
https://github.com/lesismal/arpc/blob/master/client.go#L781
https://github.com/lesismal/arpc/blob/master/client.go#L845

所以,虽然 websocket 本身不需要处理所谓的 粘包,但在默认提供的扩展中仍存在一个完整 websocket Message 可能包含多个 arpc Message 情况,所以这里需要循环处理、而不是把一个 websocket Message buffer 就当成一个 arpc Message 的 buffer

还有另一个问题是,第二次循环中,header 的内容并不存在,计算的 method 或者其他信息都是原来消息体的一部分信息,即使想要组装数据,似乎也没法完成。

上面已经讲到,一个 websocket Message 可能包含多个 arpc Message,并且本身封装的 Write 也是调用 WriteMessage,所以可以保证一个 websocket Message 中一个或者多个 arpc Message 的完整性,不需要担心 js client 解析时遇到半个 arpc Message 的问题,所以要么 offset 已经大于 websocket Message 长度结束循环,要么 headerArr 就正常拿到完整包头:
https://github.com/lesismal/arpc/blob/master/extension/jsclient/arpc.js#L182

from arpc.

spxvszero avatar spxvszero commented on June 26, 2024

上面我写的部分代码就是例子了……

可能比较麻烦,我重写了一个 Demo 打包发给您,在写的过程中我发现了另一个问题,就是如果使用这种订阅模式,另一个客户端如果不是 web 端,而是 server 端的话,会出现 timeout 的情况,在代码里我也一并打包给您了。

单纯运行 server 的程序,然后打开网页端就是我说的上述没有正确分段导致 websocket Message 截断的问题;
在运行 server 程序的前提下,在另一个终端运行 client 程序,就会出现新发现的 timeout 问题;

代码均在 main.go 中,要编译 client 程序,将 main() 里面的 server [部分代码注释,其余部分解开注释即可。
pinDemo.zip

from arpc.

lesismal avatar lesismal commented on June 26, 2024

上面我写的部分代码就是例子了……

可能比较麻烦,我重写了一个 Demo 打包发给您,在写的过程中我发现了另一个问题,就是如果使用这种订阅模式,另一个客户端如果不是 web 端,而是 server 端的话,会出现 timeout 的情况,在代码里我也一并打包给您了。

单纯运行 server 的程序,然后打开网页端就是我说的上述没有正确分段导致 websocket Message 截断的问题;
在运行 server 程序的前提下,在另一个终端运行 client 程序,就会出现新发现的 timeout 问题;

代码均在 main.go 中,要编译 client 程序,将 main() 里面的 server [部分代码注释,其余部分解开注释即可。
pinDemo.zip

你例子中的server用的是websocket,你指的超时应该是说go client的超时吧?因为你的go client用的是tcp协议,tcp连到go的 websocket上,websocket msg解析都没通。

js client我试了下是能正常收到消息的:
image

另外代码中还有一些问题,比如:

  1. BroadcastClients 没加锁
  2. 不应该为每个新连接上来的client单独设置HandleDisconnected:
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(...)

from arpc.

lesismal avatar lesismal commented on June 26, 2024

如果想既服务 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性能好。

from arpc.

lesismal avatar lesismal commented on June 26, 2024

JS Client 是能收到消息,但是被截断了,以下是浏览器的输出:

确实是,看了下代码,计算 body length 时多写了个 & 0xFF,导致只计算了第一个字节,稍等我修复更新上去。

感谢反馈!

from arpc.

lesismal avatar lesismal commented on June 26, 2024

已修复: 0f639ef

请尝试最新版本的 js client

from arpc.

spxvszero avatar spxvszero commented on June 26, 2024

赞👍

from arpc.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.