Skip to content
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

为什么server转发消息给目的client的时候要走netty而不是直接http调用呢 #65

Open
nju-Nicko opened this issue Oct 31, 2019 · 10 comments
Labels
question Further information is requested

Comments

@nju-Nicko
Copy link

RT,以clientA发消息给clientB为例,我目前梳理流程是这样的:
clientA ->(http invoke) -> router ->(http invoke) -> server,
然后server转发消息到clientB的时候是查找SessionSocketHolder,找到对应的NioSocketChannel,然后把消息write进去。
所以我的疑问是,为什么客户端发给服务端的请求直接走http,由SpringBoot的Controller受理,而server转发的请求要走netty呢?

@xijieh
Copy link

xijieh commented Nov 13, 2019

这也是我遇到的一个问题,因为cA和cB可能在不同的im服务器上面,如果直接走netty的话,那么消息发送到A服务器,这时候因为cB长连接是和B服务器,这时候还得做im服务器之间的通讯才能收发消息,所以作者才通过http这种方式发消息。但是如果一定要走netty有么有好的实现方式呢,就是路由要怎么设置

@xuxiake2017
Copy link

现实环境中,只有server端有公网环境能被访问到,client是没法被直接访问到的

@Aronzhiliangwang
Copy link

这也是我遇到的一个问题,因为cA和cB可能在不同的im服务器上面,如果直接走netty的话,那么消息发送到A服务器,这时候因为cB长连接是和B服务器,这时候还得做im服务器之间的通讯能力收发消息,所以作者才通过http这种方式发消息。但是如果一定要走netty有什么有好的实现方式呢,就是路由要怎么设置

我也是查阅了比较多开源im方案也是在考虑这个问题.如果一定要走netty的连接通讯是可以的也是我们下意识认为的im实现.netty默认有两个线程池为连接和io工作.业务确实不应该在这两个线程组执行.目前我考虑的方案是创建DefaultEventExecutor线程池跑业务(向队列发送消息,处理完毕接收回执再转发给目标.乍一看绕一圈好像netty并没有减轻压力.主要是离线消息处理).如果不在netty注册线程是没办法拿到channel对象的

@crossoverJie crossoverJie added the question Further information is requested label Mar 31, 2020
@byteflyart
Copy link

我在想除了登录注册获取服务器,发送消息为什么不直接都走netty 的tcp反而client发送消息的时候走http?短连接感觉量大了性能会降低很多呀

@zyxpain
Copy link

zyxpain commented Jun 15, 2020

RT,以clientA发消息给clientB为例,我目前梳理流程是这样的:
clientA ->(http invoke) -> router ->(http invoke) -> server,
然后server转发消息到clientB的时候是查找SessionSocketHolder,找到对应的NioSocketChannel,然后把消息write进去。
所以我的疑问是,为什么客户端发给服务端的请求直接走http,由SpringBoot的Controller受理,而server转发的请求要走netty呢?

我个人理解 这个不单单是为了实现im的功能吧。
介绍文档里也说了 可以实现消息透传。
假设 Server、router部署在云端,Client A 在局域网内。可以借助http调用router,实现对内网Client端的控制。 有些场景架构中的前置机或者堡垒机程序就是这个Client。比如需要实时对接银行、医院、各种数据私有的行政机关。

@maoruishan
Copy link

对于一个c/s架构来说,已经有了socket连接。你还是让每个client再启一个web服务,用http通信,这么做的意义何在。

@telami
Copy link
Contributor

telami commented Aug 6, 2020

期待看到一个结论🥺

@Aronzhiliangwang
Copy link

Aronzhiliangwang commented Aug 6, 2020

首先,S->C的消息走netty是没什么争议的.我想主要的问题是在C->S的消息为什么是http会让人疑惑,我觉得这点应该很好理解,如果C->S的消息也是socket那么在多im server的情况下client岂不是要保持两个长连接(route和im)?而如果是这样的话route服务器是未必可以支撑的,发送消息走http可以较好的解决route服务器的设计难度.不可否认的是http在多数情况下是比socket可靠的,那这也保证了消息的丢失率,至于作者一开始的设计思路是为何就不得而知了
ps:也不要总是纠结于轮子的设计是不是有什么深意,代码都是人写的,实际业务场景都不一样,轮子很多情况为了通用性而牺牲一些特性

@congyunlong
Copy link

congyunlong commented Aug 21, 2020

因为每个client跟服务器是通过netty建立的长连接,用户之间发送消息用http也可,再用netty也行,用netty可能没有http简单,但是http频繁的连接断开,在并发量大的时候会耗费性能,所以我觉得server之间通过netty发送消息更好一些,可以充分的利用一个连接或多个长连接。

@xiaoguyu
Copy link

个人理解。
以下讨论都是基于现有架构。发消息:client(http) -> route(http) -> server,接消息:server(netty) -> client
Q:client已经与server建立长连接,为何发消息不直接 client(netty) -> server
A:如果c1私聊c2,假设c1 <-> s1, c2 <-> s2, 因为server之间不进行通信,所以无法做到 c1 -> s1 -> s2 -> c2
Q:为何route -> server不走netty而是http
A:假设s1 -> c1, s2 -> c2,在route -> server走netty的情况下,如果c1私聊c2:c1 -> r(netty) -> s2 -> c2,如果c2私聊c1:c2 -> r(netty) -> s1 -> c1,这样route需要与s1、s2都建立长连接,这样长连接就很多了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests