# im **Repository Path**: githubsync/im ## Basic Information - **Project Name**: im - **Description**: 极客时间-IM课程代码 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-03-30 - **Last Updated**: 2023-11-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 这是极客时间专栏《即时消息技术剖析与实战》代码示例,实现了一个简易web版的聊天室。主要分成两期完成,[期中](#middle),[期末](#final)。 ## 期中示例说明 这个聊天室的大概功能有: 1. 支持用户的登录。 2. 双方支持简单的文本聊天。 3. 支持消息未读数(包括总未读和会话未读)。 4. 支持联系人页和未读数有新消息的自动更新。 5. 支持聊天页有新消息时自动更新。 ### 界面 界面上主要分成4个,一个登录界面,一个所有联系人界面,一个最近联系人界面,一个聊天页。分别如下(请原谅界面的丑陋,前端对我实在比较费劲): ![](img/login.jpg) ![](img/all_contacts.jpg) ![](img/latest_contacts.jpg) ![](img/chat.jpg) ### 框架 框架上后端用到了spring boot + JPA,前端主要是bootstrap和thymeleaf结合。 ### web服务器和资源 资源方面用到了内嵌到jvm中的h2来作为db,语法上基本和mysql一致。redis也是用到了内嵌的embedded-redis。web服务器使用spring boot内嵌的jetty。 ### 程序入口和使用 整个项目开箱即用,导入到IDE里后,执行geektime.im.lecture.Starter类就可以启动服务。服务默认端口为80,通过 http://localhost 直接访问可以进入到登录界面。默认内置了三个用户,使用邮箱和密码进行登录,登录成功后,进入到“最近联系人列表页”和“所有联系人列表页”,选择用户,点击”开始聊天“即可进行一对一私聊。用户在最近联系人页和在聊天页时,如果有新的消息到达,消息内容和未读数都会进行实时更新。 用户名 | 用户邮箱 | 用户密码 --------- | -------- | ------- 张三 | zhangsan@gmail.com | 1234 李四 | lisi@gmail.com | 1234 王五 | wangwu@hotmail.com | 1234 ### 其他代码说明 web容器启动时会自动建表以及插入默认数据,相应的数据在 resources/db 下,schema.sql是建表语句,data.sql是初始化表数据。 thymeleaf对应的页面有两个,在 resources/templates下,分别为 index.html和login.html,前者负责消息展示,后者负责登录。 ## 期末示例说明 期末我们对这个聊天室进行了较大的改造,主要的feature有: 1. 支持基于websocket的长连接。 2. 消息收发均通过长连接进行通信。 3. 基于redis的发布/订阅实现消息推送。 4. 支持消息推送的ack机制和重推机制。 5. 支持客户端的单向心跳机制和idle超时断连。 6. 支持客户端断线后的自动重连。 ### 界面 期末的界面主要在原有界面上新增了一个websocket的入口,并且支持根据长连接状态进行“上线”和“掉线”的提示。 * websocket入口位置如下图: ![](img/websocket_entrance.png) * 上线建连成功提示 ![](img/websocket_login_success.png) ### 框架 长连接的实现上采用了netty作为nio的框架,结合spring boot以及redis的“发布/订阅”功能来完成。 ### 使用相关说明 通过 http://localhost 进行登录,默认三个账号的邮箱和密码和期中的一致,登录成功后,从右上角的websocket入口进入到基于websocket的界面,此时默认会向服务端建立长连,长连建立成功后会在该页面的右上角显示”上线成功“。长连建立后,后续该界面的所有操作都会基于这个websocket长连来进行,比如消息发送、消息打开查询、消息推送接收等。 ### 其他代码说明 websocket的服务端启动入口程序在:/Sample/src/main/java/geektime/im/lecture/ws/WebSocketServer.java里,目前是通过@PostConstruct跟随主程序的Starter自动启动的,默认在8080端口监听。服务端WebSocketServer的主要配置在:/Sample/src/main/resources/application.yml里面,主要包括一下配置: ![](img/websocket_confs.png) ## 最后 该项目仅作为学习参考的demo使用,包括期末的很多功能在实现上也仅能作为示例使用,不具备线上使用标准。另外在功能上面也还有需要完善的地方,比如:离线消息的实现、群聊功能的实现等,也欢迎和期待大家一起来改进完善。 ## 本地端口不够用 [错误参考](https://zhuanlan.zhihu.com/p/471144255) 本人嵌入式小白,在测试一款4G模组A时,用wireshark工具抓TCP报文分析时,发现大量的TCP Port numbers reused报文, _**发起大量请求的时候,办公室网络都说很卡,连不上了**_ 但他能正常连接,另外我在另一款4G模组B也进行了测试,却没有发现这种报文。 后来发现,TCP Port numbers reused中的Port numbers是指本地端口,原来模组A把lwip的本地端口限制在65510到65515,一共16个,而且查看lwip源码设置time_wait时间是等于2个TCL_MSL,就是5000 milliseconds 我测试用例是间隔1分钟访问同一个网站,所以time_wait是过了的,那么是如何识别到TCP Port numbers reused? 我怀疑是wireshark工具帮我分析标志的 果不其然,我第一次测试出现TCP Port numbers reused,关闭软件,重新抓取,前15个报文没有报TCP Port numbers reused问题。 我跟踪这个问题是觉得这种黑色报文会是不正常的,但我测试的时候,每次TCP都能连接成功(不影响通信),所以不继续分析了,但不知道这种报文会有什么其他的不良影响,也希望有大佬能够说明一下。