大学生的福音学习Java最强书单推荐

大学生的福音学习Java最强书单推荐,第1张

Java最强书单推荐抓紧学习

01、入门

《Java 核心技术卷 1》

《Head First Java》

《鸟哥的 Linux 私房菜》

为什么要学 Linux 呢因为在实际的开发工作中项目基本上都要部署到 Llilux 环境下。Windows作为服务器的很少,除了慢没别的原因。

假如能够提前掌握一些 Linux 基本操作的话,不仅简历上是加分项,工作中更能快人一步。

《Maven 实战》

《Git 权威指南》

02、进阶

《Java 编程思想》

《Java编程思想》这本书确实没得说,质量很高,但需要放在 Java 入门后再去读,这样才能真正地去理解思想。

《Netty 实战》

无论是构建高性能的 Web、游戏服务器、推送系统、RPC 框架、消息中间件还是分布式大数据处理引擎,都离不开Netty,在整个行业中,Netty 广泛而成功的应用,使其成为了 Java 高性能网络编程的卓绝框架。

《代码整洁之道》

软件的质量,不仅依赖于架构,更与代码质量息息相关。而代码的质量与其整洁度成正比关系,越整洁的代码,其质量毫无疑问的就会越高。

03、深入

《重构,改善既有代码的设计》

《重构,改善既有代码的设计》

《深入理解 Nginx》

《深入剖析 Tomcat》

《JDK 里的设计模式》

《深入浅出设计模式》

《设计模式之禅》

《Head First 设计模式》

《算法》

《大型网站系统与 Java 中间件实践》

《大型网站技术架构: 核心原理与案例分析》

《亿级流量网站架构核心技术》

04、学习方法

第一,善用搜索引擎。平常需要找资料,需要解决问题,如果自己一时半会没有方法的话,就去搜。

第二,学会提问。如果搜索引擎找不到答案的话,不要直接把问题抛到群里,抛给同事、领导,或者大牛,要先对问题梳理一下。

第三,善干总结和归纳。很多同学给我反馈,“二哥,怎么总是感觉记不住啊,学完就忘啊,有什么好的办法吗

C语言基础知识的方法:

了解数据结构和算法:C 语言是一种基础的编程语言,很多算法和数据结构都是通过 C 语言实现的。因此,学习数据结构和算法可以帮助加深对 C 语言的理解,并提高编程能力。

参加在线课程或培训班: 可以参加一些在线课程或培训班来系统地学习 C 语言的基础知识。例如在 Coursera、Udemy或者网易云课堂等平台上可以找到相关的课程。

学习示例代码:

阅读代码:首先需要仔细地阅读示例代码,了解代码的功能和实现方法。可以分析代码结构,查看变量和函数的命名规范、注释说明和代码格式等。

理解代码逻辑:在阅读代码的过程中,需要尝试理解代码的逻辑。可以通过画流程图或者思维导图来帮助理解代码的实现思路和算法。

实际运行代码:在阅读完示例代码之后,可以尝试将代码运行起来,并且对代码进行调试,了解代码的具体执行过程。可以通过调试器等工具来帮助理解代码的运行过程。

修改代码:尝试修改示例代码,添加新的功能或者改进原有的代码。通过修改代码来深入理解代码的实现思路和功能特性并且可以提高自己的编程能力。

参考其他资源:如果在阅读示例代码的过程中遇到了困难,可以通过查阅相关的资料来帮助理解。例如可以参考官方文档博客文章或者在线教程等。

RSocket应用层协议支持 Reactive Streams语义, 例如:用RSocket作为HTTP的一种替代方案。在本教程中, 我们将看到RSocket用在spring boot中,特别是spring boot 如何帮助抽象出更低级别的RSocket API。

让我们从添加spring-boot-starter-rsocket依赖开始:

这个依赖会传递性的拉取RSocket相关的依赖,比如:rsocket-core 和 rsocket-transport-netty

现在继续我们的简单应用程序。为了突出RSocket提供的交互模式,我打算创建一个交易应用程序, 交易应用程序包括客户端和服务器。

31 服务器设置

首先,我们设置由springboot应用程序引导的RSocket server服务器。 因为有spring-boot-starter-rsocket dependency依赖,所以springboot会自动配置RSocket server。 跟平常一样, 可以用属性驱动的方式修改RSocket server默认配置值。例如:通过增加如下配置在applicationproperties中,来修改RSocket端口

也可以根据需要进一步修改服务器的其他属性

32设置客户端

接下来,我们来设置客户端,也是一个springboot应用程序。虽然springboot自动配置大部分RSocket相关的组件,但还要自定义一些对象来完成设置。

这儿我们正在创建RSocket客户端并且配置TCP端口为:7000。注意: 该服务端口我们在前面已经配置过。 接下来我们定义了一个RSocket的装饰器对象RSocketRequester。 这个对象在我们跟RSocket server交互时会为我们提供帮助。 定义这些对象配置后,我们还只是有了一个骨架。在接下来,我们将暴露不同的交互模式, 并看看springboot在这个地方提供帮助的。

我们从Request/Response开始,HTTP也使用这种通信方式,这也是最常见的、最相似的交互模式。 在这种交互模式里, 由客户端初始化通信并发送一个请求。之后,服务器端执行操作并返回一个响应给客户端--这时通信完成。 在我们的交易应用程序里, 一个客户端询问一个给定的股票的当前的市场数据。 作为回复,服务器会传递请求的数据。

41服务器

在服务器这边,我们首先应该创建一个controller 来持有我们的处理器方法。 我们会使用 @MessageMapping注解来代替像SpringMVC中的@RequestMapping或者@GetMapping注解

来研究下我们的控制器。 我们将使用@Controller注解来定义一个控制器来处理进入RSocket的请求。 另外,注解@MessageMapping让我们定义我们感兴趣的路由和如何响应一个请求。 在这个示例中, 服务器监听路由currentMarketData, 并响应一个单一的结果Mono<MarketData>给客户端。

42 客户端

接下来, 我们的RSocket客户端应该询问一只股票的价格并得到一个单一的响应。 为了初始化请求, 我们该使用RSocketRequester类,如下:

注意:在示例中,RSocket客户端也是一个REST风格的controller,以此来访问我们的RSocket服务器。因此,我们使用@RestController和@GetMapping注解来定义我们的请求/响应端点。 在端点方法中, 我们使用的是类RSocketRequester并指定了路由。 事实上,这个是服务器端RSocket所期望的路由,然后我们传递请求数据。最后,当调用retrieveMono()方法时,springboot会帮我们初始化一个请求/响应交互。

接下来我们将查看 Fire And Forget交互模式。正如名字提示的一样,客户端发送一个请求给服务器,但是不期望服务器的返回响应回来。 在我们的交易程序中, 一些客户端会作为数据资源服务,并且推送市场数据给服务器端。

51服务器端

我们来创建另外一个端点在我们的服务器应用程序中,如下:

我们又一次定义了一个新的@MessageMapping路由为collectMarketData。此外, Spring Boot自动转换传入的负载为一个MarketData实例。 但是,这儿最大的不同是我们返回一个Mono<Void>,因为客户端不需要服务器的返回。

52 客户端

来看看我们如何初始化我们的fire-and-forget模式的请求。 我们将创建另外一个REST风格的端点,如下:

这儿我们指定路由和负载将是一个MarketData实例。 由于我们使用send()方法来代替retrieveMono(),所有交互模式变成了fire-and-forget模式。

请求流是一种更复杂的交互模式, 这个模式中客户端发送一个请求,但是在一段时间内从服务器端获取到多个响应。 为了模拟这种交互模式, 客户端会询问给定股票的所有市场数据。

61服务器端

我们从服务器端开始。 我们将添加另外一个消息映射方法,如下:

正如所见, 这个处理器方法跟其他的处理器方法非常类似。 不同的部分是我们返回一个Flux<MarketData>来代替Mono<MarketData>。 最后我们的RSocket服务器会返回多个响应给客户端。

62客户端

在客户端这边, 我们该创建一个端点来初始化请求/响应通信,如下:

我们来研究下RSocket请求。 首先我们定义了路由和请求负载。 然后,我们定义了使用retrieveFlux()调用的响应期望。这部分决定了交互模式。 另外注意:由于我们的客户端也是REST风格的服务器,客户端也定义了响应媒介类型MediaTypeTEXT_EVENT_STREAM_VALUE。

这里我们给异常处理方法标记注解为@MessageExceptionHandler。作为结果, 这个方法将处理所有类型的异常, 因为Exception是所有其他类型的异常的超类。 我们也可以明确地创建更多的不同类型的,不同的异常处理方法。 这当然是请求/响应模式,并且我们返回的是Mono<MarketData>。我们期望这里的响应类型跟我们的交互模式的返回类型相匹配。

先以开发者的角度:

PHP跟net根本就不是一个级别的,net无论是应用场合、开发环境、帮助文档、编写风格、运行效率全部吊打PHP;PHP之所以流行就是因为很多开源框架都是现成的,刚好符合国人拿来主义的精神,修修改改就能拿来卖钱了。

JAVA各方面体量大致跟net旗鼓相当,Windows系统下还是net的天下,企业应用方面JAVA占用率高些,移动开发方面因为安卓和苹果的原因,net失去了先机。微软正在逐步赶超,unitiy、net core都在表明微软的态度。

以成本的角度:

微软的产品哪都好,就是版权太贵,Windows系统要钱,office要钱,服务器要钱,sqlserver要钱,再高级点用用企业版、集群之类的,做一个项目下来才能挣多少钱,都给微软了。PHP之所以能存活,就是linux免费,MySQL免费,Apache免费,PHP免费,就连框架都免费;JAVA跟PHP差不多。这种生态下导致了代码资源非常丰富,天下一般抄,开发成本就更低了。所以不是微软的东西不好,是JAVA和PHP开发成本太低了。用过对比你会发现,贵有贵的道理,所有开发帮助文档中,没有比微软做的更详尽的。

如果你是一个独立开发者,首选net,Windows桌面应用、Windows服务、Windows 游戏 、网站、webservice、unity 游戏 ,除了安卓和苹果原生应用,net都能胜任。如果微软可以在安卓下造出类似framework的东西,那就一统天下了。

做了7年的c#开发,4年多的java,c/c++,说说我的看法,主要有的区别:

一是开源和闭源的区别,net早期完全闭源,开发也是完全傻瓜式的,微软的思想就是让开发更容易,所以无法看到底层实现,给人的感觉就是走一条胡同,很快到达目的地却无法知道墙内的东西,接触过java和c之后,感觉就像掉进了大海,原来海底也这么漂亮,有太多开源的软件和框架,你可以看到更深层的东西,比如我们看dubbo,看进去后看netty,netty看进去后看到Linux,select,epoll,看到epoll,看Linux相关的,感觉就是掉进了大海,太多东西需要学习,做这么多年开发依然在不断的学习,但也给了我更多兴趣和探知未知世界的乐趣,以前做net的时候有种感觉就是,别让我做非net的东西,我不会,对陌生的的东西很害怕,现在的感觉就是你让我写个控制原子弹的程序我也敢去写(比方)。

二是免费和收费的区别,所有的公司产品的成本是公司发展的最关键因素之一,net全家桶成本太高,vs的版权+windows版权+sql server版权再加上其它支持类软件版权,成本非常高,相反linux完全免费开源,给你选你会选哪一个?同时linux或从Unix而来,但天生具有轻量级性能可以发挥到极致而且稳定的系统,而windows为个人和办公而设计,界面和系统其它资源就让系统占用一部分,感觉很笨重,上天做一个长连接测试,单台Linux轻松上几十万,当然由于内存原因,否则可以上百万,而windows就很难做到,而且Linux哪里不行你可以去改的,windows就不行了,所以一个稳定高效免费的还有一大堆开源支持的,和一个收费性能相比没有那么高效的,好多公司自然选择前者

三是开发效率,上面说两点都说net处于下风,但net不是一无是处,net有自身的优点,那就是开发效率,net在java之上做了改进,让开发人员更容易开发,语言优美,做企业应用开发是很好的工具,可以快速出结果,你用其它开发要么大炮打蚊子,要么不稳定,在工厂和企业就要求很快做出来,这是net优势,所以有他的市场份额,说这么多发现没个图,有评论的传一张

为什么PHP、Java在市面上比NET要受欢迎?而且从各大招聘网站上看PHP、Java的岗位比NET岗位要多很多。

其实NET也是有不少的优点的:

但是,它的致命缺点是:

设想一下,一个企业,如果服务器众多,那系统费用、数据库的授权费用,是多么庞大的一笔支出!

而PHP、Java则不同,它们都是跨平台开源免费的,虽然Java开始收费了(但还有免费的OpenJDK),所以PHP、Java还是首选。

我自己当初学过net,java,现在算是略有了解。 就我个人理解, 许多公司不用net 语言的根本原因,就是 net 在最初的时候不开源,教程少,入门较难,而且最后正式发行程序什么,还要交钱,所以在许多公司中首选java这种开放语言,教程多,入门简单,基本不收费(不收费是关键,划重点) 。这也算是开源与闭源软件之争吧,最终以java为首的开源软件获胜,得以普及。

后来,开源软件已经是大势所趋,这时候微软net阵营已经做了许多改变。我最熟悉net中的c#语言,我就以c#为例说说吧。

微软以前信奉闭环,所有语言都不支持跨平台,也就没有c#;后来java越来越发展壮大,net感受到了巨大危险,于是就模仿java,net提出了c#,借以打击java。c#很像java语言,而且和java一样能够跨平台,windows、linx、android、ios都可以编程,这就是微软做的改变。

如果大家用过c#或者vb,c++来编写窗口程序,就会发现,这些语言写出来的windows窗口太棒了,而用java写出来的窗口程序,不敢恭维,太丑了,这也就是我后来学习c#的原因。(这也就是为什么说跨平台只是一个美梦而已)。

跨平台、开源之后的 net ,其实跟java的基础结构并不差多少,但不具备数量优势,也就是说:java由于之前用的人太多了,各个方面的创新、发展都比较完善,有着坚实的用户群体、应用基础;而 net ,由于是后发,已经失去了太多的应用环境,自然现在许多公司在不考虑是专为windows开发的情况下,是不会太主动使用net。

如果用户采用微软全家桶解决方案, Net 的开发效率和体验是完全可以吊打 Java 和 PHP 的, 但昂贵的价格, 让开发者和用户又爱有恨

其实 Net + C# 现在虽说不如一票跨平台框架语言用得人多, 但也远远谈不上没落

在这个问题上, 个人认为 Microsoft 的原 CEO Steve Ballmer 难辞其咎, 在 Windows 霸主地位已经开始崩溃的时候 依然固执坚持封闭生态, 导致当时的 Net 开发者 无不焦虑和彷徨

不过 2014 年 Satya Nadella 接任 CEO 后, 微软 逐渐采取了 务实 开放 的做法, 收购 Xamarin 整合进 IDE, 推出 Visual Studio 社区版, C# 开始免费和跨平台, Microsoft 越来越像 Oracle, C# 越来越像 Java, 多多少少缓解了开发者的忧虑, 不少开发者开始回归, 毕竟 C# 优雅的语法 和 Visual Studio 卓越的开发体验 确实让人难以割舍

Net以前是不开源的,需要收费,有着各种版权问题,导致其语言生态发展不够。有其语言优点,但是从公司发展成本上来考虑,就注定不能作为首选。

PHP未兴起之前,很多公司使用net来开发网站,因为相比较java的JSP,开发效率也还是要高一些,这对中小型企业的业务快速变更升级很重要。JSP运行速度会快一些,但其需要编译的特点,开发速度会相对缓慢。而对中小型企业来说,时间就是金钱,开发速度太慢,跟不上业务发展是很致命的。

之后PHP应运而生,其语言设计的初衷就是为了快速开发web应用。完全的开源免费,开发效率非常高,甚至一个人就可以搞定一个项目。中小型公司,从发展之初的考虑,逐渐将PHP作为首选发展语言。

随着PHP生态的逐渐强大,net这种生态落后,开发速度比不上PHP,运行速度比不上JSP的语言也就逐渐没落了。

现在也有很多发展好了的公司,做大了做强了,又开始将自己的PHP项目往JSP迁移,因为开始追求运行速度。

所以PHP基本占领了中小型公司,而大公司则更多选择JSP。这都是语言的特性和优势决定的,将来如果出现一种语言能同时兼有开发速度和运行速度的免费开源的语言,那PHP和JSP也会逐渐走上net这条路。一切都是企业成本和效率的问题。

+++++++++++++++++++++++++++++++++++++

第一次写问答,没想到有这么高的阅读量。

有些人说我对net的认识太落后了,好吧,我开始学编程的时候,net确实是比较封闭的状态,这些年我也不再去关注net,对它的进一步了解也都是通过身边的同学朋友侧面反映的。

然后,真实情况是,我身边所有学net的同学都转行了。因为岗位少,薪资低,真的生存很艰难哩。

遥想当年,我们一个宿舍的同学(一群穷逼,只能住在学校破旧的8人大宿舍里,因为住宿费真便宜啊 ),开始讨论选某个语言作为今后学习方向。有人选择了net,有人选择了PHP,有人选择了JSP,然后各自努力。

现在,再来看彼此发展,net的同学都转行了,PHP的都在中小型公司,JSP的在平安保险这种大公司里。薪资待遇对比,net的同学和我们也有了差距。如果只看基本工资的话,还是PHP的高,哈哈。但是,加上年终奖就扑街了。我们同在深圳的经常一起出来聚聚,中小型公司的经常自嘲,辛辛苦苦一整年,比不上一个年终奖。唉,大公司年终奖是真多啊,可以顶你大半年甚至一年的工资,人比人气死人。

当然,学PHP也不是都好,有个同学受不了压力转行做SEO了。也不是所有学java都好,我现在公司的测试就是个学java找不到工作,转而当测试的。

其实问题还是经验,有多年工作经验,就是你找工作最好的敲门砖了。

最后,没有最好的语言,适应市场发展的语言就是好语言。

各位看官,不喜勿喷!

简单的说几句,就几句。我司用net做web,推送服务器,消息服务器,数据握手服务,cad应用二次开发,gis应用,各种手持设备应用,各种服务窗口用的终端应用,视频监控等等等,你还觉得php真的能打过net么?

个人的观点:

1、php肯定比不过net了,用他主要是网站那块而已。

2、net和Java,单纯从语言c#比java优秀,开源生态肯定是Java,效率是c#

3、net效率不高,在于windows平台,现在跨平台了,linux性能高于windows。

Net core 有一定的机会。

这个答案有几点:

1、运行环境成本问题,在net core出来之前,net

需要的运行环境搭设成本高,windows服务器正版上万,用access做数据库也需要几千元的正版office,虽说sql express是免费的,但是阉割的太厉害。所以一般win虚拟主机或者服务器都基本上比linux的贵,尤其是海外注重版权地区,更是差至少一半,所以造成了php大行其道,因为他的运行环境几乎零成本,而且服务器需要的配置可以很低,甚至128m内存就可以跑php程序。

2、开发环境成本问题,一样的毛病,code出来之前,开发net程序的工具首选visual studio,但是正版的也要几千上万,不是一般人承受的起的。而php和java的免费又好用的开发工具又很多,因此php又获得了先机。

3、学习成本问题,net之前,微软平台应用系列的开发需要太多,vb,c,c++,而网页脚本语言是基于vbscript的asp,随着系统的发展,这些需要和脚本逐步跟不上时代对敏捷开发、更复杂系统开发的需求,因此推出了aspnet和c#、f#,vbnet等语言,网页方面使用aspnet开发又一直升级,net 20,30,35,到现在的47x,每次升级都带来了新的概念,如今为了抢回份额,推出了net core 也是升级了好几个版本,所以net的开发要不断的学习,学习,升级,升级。而php就不一样了,版本的升级基本上都是框架内的升级,学习成本明显低于net

4、资源丰富问题,如上所述,由于成本问题,很多人选择了php开发,然后php的免费框架越来越多,程序员一般都懒,拿来修修改改就能上线,接着做下个项目就可以啦,而net明显没那么多免费框架,市面上分许多net框架是要授权费的。

不过目前微软的发力,也在着手改善这种问题,发布了visual studio code,visual studio community免费开发工具开发成本明显降低,net code跨平台语言只要版本符合要求linux系统也可以运行net code开发的程序了。如果能够有支持linux的文件型的数据库软件(例如office的access)发布就更好了。

做一个企业,最主要的目标是生存。活下来,才是根本目标,说好听一点,就是可持续发展。微软的生态圈大多收费,价格不菲,虽然从性能,入门,易用性来说,Net都好于Java领域,好于JSP和PHP,无奈中国市场竞争激烈,企业研发成本是首选考虑的因素,尤其是在中美贸易战的背景下,美国要加强知识产权保护的前提下,使用方用Net产品和服务就要支付昂贵的版权费用,让人承受不起。那么,免费开源的非Net体系,就会受到很多企业青睐,企业只要承担人工成本,不用过多支付版权费,是企业不得不考虑的方面。所以,现在使用什么技术,未来使用啥技术,是市场竞争的结果,要把握住这种趋势,才能占有先机。

CIM(CROSS-IM) 一款面向开发者的 IM(即时通讯)系统;同时提供了一些组件帮助开发者构建一款属于自己可水平扩展的 IM 。

借助 CIM 你可以实现以下需求:

下面来看看具体的架构设计。

整体主要由以下模块组成:

cim-server

IM 服务端;用于接收 client 连接、消息透传、消息推送等功能。

支持集群部署。

cim-forward-route

消息路由服务器;用于处理消息路由、消息转发、用户登录、用户下线以及一些运营工具(获取在线用户数等)。

cim-client

IM 客户端;给用户使用的消息终端,一个命令即可启动并向其他人发起通讯(群聊、私聊);同时内置了一些常用命令方便使用。

整体的流程也比较简单,流程图如下:

所以当我们自己部署时需要以下步骤:

接下来重点看看具体的实现,比如群聊、私聊消息如何流转;IM 服务端负载均衡;服务如何注册发现等等。

IM 服务端

先来看看服务端;主要是实现客户端上下线、消息下发等功能。

首先是服务启动:

由于是在 SpringBoot 中搭建的,所以在应用启动时需要启动 Netty 服务。

从 pipline 中可以看出使用了 Protobuf 的编解码(具体报文在客户端中分析)。

注册发现

需要满足 IM 服务端的水平扩展需求,所以 cim-server 是需要将自身数据发布到注册中心的。

所以在应用启动成功后需要将自身数据注册到 Zookeeper 中。

最主要的目的就是将当前应用的 ip + cim-server-port+ http-port 注册上去。

上图是我在演示环境中注册的两个 cim-server 实例(由于在一台服务器,所以只是端口不同)。

这样在客户端(监听这个 Zookeeper 节点)就能实时的知道目前可用的服务信息。

登录

当客户端请求 cim-forward-route 中的登录接口(详见下文)做完业务验证(就相当于日常登录其他网站一样)之后,客户端会向服务端发起一个长连接,如之前的流程所示:

这时客户端会发送一个特殊报文,表明当前是登录信息。

服务端收到后就需要将该客户端的 userID 和当前 Channel 通道关系保存起来。

同时也缓存了用户的信息,也就是 userID 和 用户名。

离线

当客户端断线后也需要将刚才缓存的信息清除掉。

同时也需要调用 route 接口清除相关信息(具体接口看下文)。

IM 路由

从架构图中可以看出,路由层是非常重要的一环;它提供了一系列的 HTTP 服务承接了客户端和服务端。

目前主要是以下几个接口。

注册接口

由于每一个客户端都是需要登录才能使用的,所以第一步自然是注册。

这里就设计的比较简单,直接利用 Redis 来存储用户信息;用户信息也只有 ID 和 userName 而已。

只是为了方便查询在 Redis 中的 KV 又反过来存储了一份 VK,这样 ID 和 userName 都必须唯一。

登录接口

这里的登录和 cim-server 中的登录不一样,具有业务性质,

为了实现只能一个用户登录,使用了 Redis 中的 set 来保存登录信息;利用 userID 作为 key ,重复的登录就会写入失败。

获取一台可用的路由实例也比较简单:

当然要获取 Zookeeper 中的服务实例前自然是需要监听 cim-server 之前注册上去的那个节点。

具体代码如下:

也是在应用启动之后监听 Zookeeper 中的路由节点,一旦发生变化就会更新内部缓存。

群聊接口

这是一个真正发消息的接口,实现的效果就是其中一个客户端发消息,其余所有客户端都能收到!

流程肯定是客户端发送一条消息到服务端,服务端收到后在上文介绍的 SessionSocketHolder 中遍历所有 Channel(通道)然后下发消息即可。

服务端是单机倒也可以,但现在是集群设计。所以所有的客户端会根据之前的轮询算法分配到不同的 cim-server 实例中。

因此就需要路由层来发挥作用了。

路由接口收到消息后首先遍历出所有的客户端和服务实例的关系。

路由关系在 Redis 中的存放如下:

由于 Redis 单线程的特质,当数据量大时;一旦使用 keys 匹配所有 cim-route: 数据,会导致 Redis 不能处理其他请求。

所以这里改为使用 scan 命令来遍历所有的 cim-route:。

接着会挨个调用每个客户端所在的服务端的 HTTP 接口用于推送消息。

在 cim-server 中的实现如下:

cim-server 收到消息后会在内部缓存中查询该 userID 的通道,接着只需要发消息即可。

在线用户接口

这是一个辅助接口,可以查询出当前在线用户信息。

实现也很简单,也就是查询之前保存 ”用户登录状态的那个去重 set “即可。

私聊接口

之所以说获取在线用户是一个辅助接口,其实就是用于辅助私聊使用的。

一般我们使用私聊的前提肯定得知道当前哪些用户在线,接着你才会知道你要和谁进行私聊。

类似于这样:

在我们这个场景中,私聊的前提就是需要获得在线用户的 userID。

所以私聊接口在收到消息后需要查询到接收者所在的 cim-server 实例信息,后续的步骤就和群聊一致了。调用接收者所在实例的 HTTP 接口下发信息。

只是群聊是遍历所有的在线用户,私聊只发送一个的区别。

下线接口

一旦客户端下线,我们就需要将之前存放在 Redis 中的一些信息删除掉(路由信息、登录状态)。

IM 客户端

客户端中的一些逻辑其实在上文已经谈到一些了。

登录

第一步也就是登录,需要在启动时调用 route 的登录接口,获得 cim-server 信息再创建连接。

登录过程中 route 接口会判断是否为重复登录,重复登录则会直接退出程序。

接下来是利用 route 接口返回的 cim-server 实例信息(ip+port)创建连接。

最后一步就是发送一个登录标志的信息到服务端,让它保持客户端和 Channel 的关系。

自定义协议

上文提到的一些登录报文、真正的消息报文这些其实都是在我们自定义协议中可以区别出来的。

由于是使用 Google Protocol Buffer 编解码,所以先看看原始格式。

其实这个协议中目前一共就三个字段:

目前主要是三种类型,分别对应不同的业务:

心跳

为了保持客户端和服务端的连接,每隔一段时间没有发送消息都需要自动的发送心跳。

目前的策略是每隔一分钟就是发送一个心跳包到服务端:

这样服务端每隔一分钟没有收到业务消息时就会收到 ping 的心跳包:

内置命令

客户端也内置了一些基本命令来方便使用。

比如输入 :q 就会退出客户端,同时会关闭一些系统资源。

当输入 :olu(onlineUser 的简写)就会去调用 route 的获取所有在线用户接口。

群聊

群聊的使用非常简单,只需要在控制台输入消息回车即可。

这时会去调用 route 的群聊接口。

私聊

私聊也是同理,但前提是需要触发关键字;使用 userId;;消息内容 这样的格式才会给某个用户发送消息,所以一般都需要先使用 :olu 命令获取所以在线用户才方便使用。

消息回调

为了满足一些定制需求,比如消息需要保存之类的。

所以在客户端收到消息之后会回调一个接口,在这个接口中可以自定义实现。

因此先创建了一个 caller 的 bean,这个 bean 中包含了一个 CustomMsgHandleListener 接口,需要自行处理只需要实现此接口即可。

自定义界面

由于我自己不怎么会写界面,但保不准有其他大牛会写。所以客户端中的群聊、私聊、获取在线用户、消息回调等业务(以及之后的业务)都是以接口形式提供。

也方便后面做页面集成,只需要调这些接口就行了;具体实现不用怎么关心。

cim 目前只是第一版,BUG 多,功能少(只拉了几个群友做了测试);不过后续还会接着完善,至少这一版会给那些没有相关经验的朋友带来一些思路。

欢迎工作一到五年的Java工程师朋友们加入Java程序员开发: 721575865

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

嗯 channel实际就是一个客户端和server的一个抽象的管道 ,netty封装了网络的底层 所以 你不必太多去掀开一些它封装的东西来处理 对于还不熟悉的开发者来讲的 话;你可以这样处理 在连接上来的时候 你创建一个session会话来持有这个channel ,每一个session有一个ID ,那么 你在业务层就可以通过这个ID拿到session 从而将这个数据发送出去,你这里 其实在服务器端就是sessionA sessionB ,A,B两个客户端连接服务器了 ,那么 就创建sessionA sessionB ,并产生一个ID (ID 保持唯一就可以了),A向B发送,那么实际就是通过服务器来转发A的消息到B,那么你必然拿到B的ID,几在A的消息中发送B的ID,这样就可以拿到sessionB ,然后channelwrite(); 消息的转发 与消息的推送 关键就在与知道sessionID,顺利得到相应的session 这样就可以解决问题了;

创建session的位置在channelActive(ChannelHandlerContext ctx);标记channel的方式很多 ,上面的和你描述的一样 只是 封装了一个session来持有channel罢了;

谢谢你的回复。

你的回复里面没有提到如何绑定用户和channel的对应关系。我对此的大致想法是这样的:客户端与服务端建立连接的时候,也就是在channelActive(ChannelHandlerContext ctx),服务端用RSA算法生成一对公私钥,并把公钥返回给客户端;客户端使用公钥加密登录信息发送到服务器,服务器解密后,将用户信息与channel对应起来,记录在链表里面。然后当A发送信息给B的时候,服务器从链表里面找到B的信息,并通过B对应的channel传送信息给B。

不知我这样的连接流程有没有问题,请指教。

ID--session--channel 它们是一一对应的, map<ID,session>;

class session{

ID;//session持有ID

channel;//session持有channel

}

任何一个客户端链接上来,你就把服务器现在在线的ID同步给链接上来的客户端,这样就好像是qq,向谁发送? 只需 ID(目标)+message; 额 你这个是可以的 变相的其实本质一样 ,ID 就是一个纽带;

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » 大学生的福音学习Java最强书单推荐

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情