crossoverjie / cim Goto Github PK
View Code? Open in Web Editor NEW📲cim(cross IM) 适用于开发者的分布式即时通讯系统
Home Page: https://crossoverjie.top/categories/Netty/
License: MIT License
📲cim(cross IM) 适用于开发者的分布式即时通讯系统
Home Page: https://crossoverjie.top/categories/Netty/
License: MIT License
Could not autowire. There is more than one bean of 'CounterService' type.
Beans:
counterService (MetricRepositoryAutoConfiguration.class) counterService (MetricRepositoryAutoConfiguration.class)
你的消息是怎样保证不丢不重的,这个我在文档中没有看到,我之前也从事过IM相关的工作,所以对IM也比较感兴趣
我看了你在51cto里面得关于im的集群的实现方案,不知道你们有没有微信交流群或者其他在线交流的方式,做了好几年的java了最近在做一个即时通讯的聊天软件,倒也开发出来了,只是不知道这其中的某些实现方案是否是最优的或者是业界先进的? 所以想进去和大家交流一些想法,如果有请把微信群,QQ,钉钉拉我一下,谢谢!我微信classmisschen,不胜感激
可以试试用protobuf重写一下
博主在crossoverjie.top/ 文章我看不见图片,请看下。
客户端重连只是根据心跳来进行判断对吧?
报错之后,监控平台便不显示已经注册的服务。使用环境 eclipse Version: Photon Release (4.8.0),jdk1.8
错误如下:
2018-08-27 14:25:08.081 WARN 19440 --- [nio-8888-exec-1] o.s.c.n.zuul.web.ZuulHandlerMapping : No routes found from RouteLocator
2018-08-27 14:25:13.600 INFO 19440 --- [nio-8888-exec-2] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header
Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:422) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:683) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.16.jar:8.5.16]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.16.jar:8.5.16]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CIMClient': Invocation of init method failed; nested exception is io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection timed out: no further information: /172.17.48.1:11211
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
您好,我有一个疑惑向您请教一下,路由模块(cim-forward-route)的出现就是为了提高吞吐量,服务高可用吗,如果不用这个模块,业务处理放在服务端,多写几个handler处理业务,服务集群用nginx负载均衡是不是也可以?
Do support client use Websocket connect to server now?
传输的协议用的是protobuf.如果要开发B/S的应用.需要WebSocket协议对吗?
如果用现在这种方式可以开发B/S应用吗?
哈哈
Bug 描述
A clear and concise description of what the bug is.
复现
复现步骤:
预期结果
A clear and concise description of what you expected to happen.
截图
If applicable, add screenshots to help explain your problem.
附加信息
Add any other context about the problem here.
是否会支持客户端发送消息也通过Netty推送呢?
目前好像只是由服务端提供了消息的下发,下游client调用服务端提供的api进行消息发送。
哈哈哈哈哈,我无处安放的表情包
以一个私聊为例,我目前理解如下:
client ->(登录) router
router ->(一致性哈希) 发现server,记录路由
client ->(私聊请求) router
router ->(根据路由把请求转发到指定的server处理) server
server ->(请求透传) router
router ->(发现路由) 目的client
我对从server到目的client的时序逻辑不是很确认,请教下是否是这样
route 服务登陆后返回的 server 服务地址与 client 网络不可达时,server 服务无法通过 tcp 链接的断开触发 offLine 接口清除路由信息
Bug 描述
A用户登录后,获取到的是Bserver的地址,连接的是Bserver
C用户登录后,获取到的是Dserver的地址,连接的是Dserver
此时A用户向C用户发送消息的话,Bserver上转发消息时,找不到C用户的channel,所以用户的会话是不是应该通过缓存共享,而不是内存呢
客户端重连代码:
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (shutDownMsg == null) {
shutDownMsg = SpringBeanFactory.getBean(ShutDownMsg.class);
}
//用户主动退出,不执行重连逻辑
if (shutDownMsg.checkStatus()) {
return;
}
if (scheduledExecutorService == null) {
scheduledExecutorService = SpringBeanFactory.getBean("scheduledTask", ScheduledExecutorService.class);
}
LOGGER.info("客户端断开了,重新连接!");
// TODO: 2019-01-22 后期可以改为不用定时任务,连上后就关闭任务 节省性能。
scheduledExecutorService.scheduleAtFixedRate(new ReConnectJob(ctx), 0, 10, TimeUnit.SECONDS);
}
可以看到这边是用了jdk的scheduledExecutorService定时任务,每隔10秒发起重连一次,但是如果重连成功了不就应该停止这个定时任务吗。
看了下代码,有些不解,请问下:
看了下发送和接收的数据结构的名称不一样
发送的结构是 CIMRequestProto.CIMReqProtocol
接收的结构是 CIMResponseProto.CIMResProtocol
理论上2进制数据应该是一样 的吧?如果那样,为什么不用一种?还是说在上层做业务区分?
问题比较低级,还望不吝赐教
我看cim
中有使用单独的线程池这种方式去处理,可网上又有文章和问题不赞成使用这类方式,有些疑惑
所以handle
中耗时业务该究竟怎样处理?希望能抽空解答一下
pipeline.addLast(nioEventLoopGroup, new Handler());
顺便还有个小问题:
什么时候handle
该使用@Sharable
注解,而非每个Channel
使用不同的handle
RT,以clientA发消息给clientB为例,我目前梳理流程是这样的:
clientA ->(http invoke) -> router ->(http invoke) -> server,
然后server转发消息到clientB的时候是查找SessionSocketHolder,找到对应的NioSocketChannel,然后把消息write进去。
所以我的疑问是,为什么客户端发给服务端的请求直接走http,由SpringBoot的Controller受理,而server转发的请求要走netty呢?
启动命令:
java -jar /data/app/cim-client-1.0.0-SNAPSHOT.jar --server.port=8084 --cim.user.id=123456 --cim.user.userName=zhangsan --cim.group.route.request.url=http://10.19.151.154:8083/groupRoute --cim.server.route.request.url=http://10.19.151.154:8083/login
Bug 描述
启动报错,无法启动client
路由模块可不可以去掉,发送消息就跟客户端注册那样,channel发送到服务端处理,不调用http接口?
Bug 描述
客户端重连服务端的定时任务一直执行,没有关闭重连任务
代码
@OverRide
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (shutDownMsg == null){
shutDownMsg = SpringBeanFactory.getBean(ShutDownMsg.class) ;
}
//用户主动退出,不执行重连逻辑
if (shutDownMsg.checkStatus()){
return;
}
if (scheduledExecutorService == null){
scheduledExecutorService = SpringBeanFactory.getBean("scheduledTask",ScheduledExecutorService.class) ;
}
LOGGER.info("客户端断开了,重新连接!");
// TODO: 2019-01-22 后期可以改为不用定时任务,连上后就关闭任务 节省性能。
scheduledExecutorService.scheduleAtFixedRate(new ReConnectJob(ctx),0,10, TimeUnit.SECONDS) ;
}
请问一下,看了一些文章,说哈希是环形的,有固定长度,看了你的common模块的treemap,你是一个个去比较大小,相邻的就是命中的节点,请问这里是可以改进的还是本来就这样就行了
实现的功能就是 js 端 websocket 连接用于接收消息,发送消息通过 http 请求到 java 提供的服务,然后这个 java 服务推送 消息到 websocket 上面,所以就需要 netty 启用的 服务既 支持 java 写的客户端 tcp 连接 又 支持 js 前端的 websocket 连接
这里有部分代码,但是没有实现这个功能:https://github.com/lmxdawn/netty-demo/tree/master/src/main/java/com/example/nettydemo/websocket3
传输的协议用的是protobuf.如果要开发B/S的应用.需要WebSocket协议对吗?
如果用现在这种方式可以开发B/S应用吗?
登录鉴权要放到长连接里面的第一帧命令里吧。登录可以请求http返回token,长连接建立之后,第一帧发送的应该是login 鉴权命令,成功后才能后续操作。
该视频已无法播放,因为与其关联的 YouTube 帐号已终止。
C#客户端
这是TreeMap的源码.
public class TreeMapConsistentHash extends AbstractConsistentHash {
private TreeMap<Long,String> treeMap = new TreeMap<Long, String>() ;
/**
* 虚拟节点数量
*/
private static final int VIRTUAL_NODE_SIZE = 2 ;
@Override
public void add(long key, String value) {
for (int i = 0; i < VIRTUAL_NODE_SIZE; i++) {
Long hash = super.hash("vir" + key + i);
treeMap.put(hash,value);
}
treeMap.put(key, value);
}
这里存在一个bug啊,当有一个节点下线时,虽然ServerCache更新了,
但这里的treeMap里面的数据是一直存在的.那么在获取路由时就会获取到已经下了线的Netty服务器地址.
router没有集群的话,应该会成为性能瓶颈吧,另外,socket的客户端和服务端都应该有收到消息的回执吧,接受者离线,应该有专门处理离线消息的模块
在 client login 的时候,userLogin 方法会向 Route 发送验证登录信息。让人疑惑的事,Route 去 Redis 中检查这个 client 是否存在,在接下来的 if 判断语句中,如果这个 client 不存在,返回的居然是已登录 - -! 这里非常不明白,是个 bug 吗
[INFO] --- spring-boot-maven-plugin:1.5.6.RELEASE:repackage (default) @ cim-server ---
[WARNING] Error injecting: org.springframework.boot.maven.RepackageMojo
java.lang.NoClassDefFoundError: org/apache/maven/shared/artifact/filter/collection/ArtifactsFilter
at java.lang.Class.getDeclaredConstructors0 (Native Method)
at java.lang.Class.privateGetDeclaredConstructors (Class.java:2671)
at java.lang.Class.getDeclaredConstructors (Class.java:2020)
at com.google.inject.spi.InjectionPoint.forConstructorOf (InjectionPoint.java:245)
at com.google.inject.internal.ConstructorBindingImpl.create (ConstructorBindingImpl.java:115)
at com.google.inject.internal.InjectorImpl.createUninitializedBinding (InjectorImpl.java:706)
at com.google.inject.internal.InjectorImpl.createJustInTimeBinding (InjectorImpl.java:930)
at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive (InjectorImpl.java:852)
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:repackage (default) on project cim-server: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:repackage failed: A required class was missing while executing org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:repackage: org/apache/maven/shared/artifact/filter/collection/ArtifactsFilter
[ERROR] -----------------------------------------------------
[ERROR] realm = plugin>org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/E:/hezehong/maven_repository/org/springframework/boot/spring-boot-maven-plugin/1.5.6.RELEASE/spring-boot-maven-plugin-1.5.6.RELEASE.jar
[ERROR] urls[1] = file:/E:/hezehong/maven_repository/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import from realm ClassRealm[maven.api, parent: null]]
[ERROR]
[ERROR] -----------------------------------------------------
[ERROR] : org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
你好,我看代码中,并没有专门对消息顺序进行处理,是否有出现消息乱序的可能,在设计时,对这方面是怎么考虑的呢?比如,在http调用的过程中,可能出现的网络延时导致的消息乱序?
cp /cim/cim-client/target/cim-client-1.0.0-SNAPSHOT.jar /xx/work/route0/
cd /xx/work/route0/
java -jar cim-client-1.0.0-SNAPSHOT.jar --server.port=8084 --cim.user.id=唯一客户端ID --cim.user.userName=用户名 --cim.group.route.request.url=http://路由服务器:8083/groupRoute --cim.server.route.request.url=http://路由服务器:8083/login
我看到cim-client里有一个IndexController入口,会接受http请求然后通过netty把请求发给cim-server的netty监听端口。
所以为什么要有IndexController这一层,只是因为是用的springboot框架吗?
通过tomcat实现的http服务发送消息,线程过多的话会不会对netty服务器的io有影响
是否有其他更好的解决方案
譬如,在netty服务端起一个消息消费的客户端,所有的要发的路由消息,放到mq中,由mq统一管理,这种否可行
移动端开发者如果想参与做移动客户端的集成开发是不是需要您提供一些接口文档和说明
现在项目是一个完整的项目可以把实现过程列出来吗?
比如说:SpringBoot 整合长连接心跳机制 没有实现步骤,只有一些关键代码,能把实现步骤列出来吗?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.