## 1.效果展示
第一次写博客,不知道怎么放置录制好的视频,所以只能放几张图片作为效果图
## 2.知识储备
传统的HTTP协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的,换做im也是同样的道理,当然也可以利用轮训的方式去查看服务器是否有新的数据,但是这种方式会有请求压力大和消息的实时性不够的弊端。
而webSocket的出现是让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方,这样在im的实现上就能够满足两个用户之间正常的通讯。
webSocket在实现上主要是分成四个步骤
1. 连接到Socket服务器
2. 监听来自服务器的消息
3. 将数据发送到服务器
4. 关闭Socket连接
## 3.实现思路
在描述实现过程前,我想来想去觉得还是有必要先大概描述一下我的实现思路:
1.首先用户的个人信息是在模拟器启动后,连接到Socket之前自动生成唯一用户,并且将用户通过flutter的SharedPreferences存储到本地,之后热更新或者热重启,先查找本地是否存在该用户,如果有该用户只将用户信息赋值给接下来执行的变量来保证用户的不可重复和持久性。
2.在我的实现中,我自己利用js在本地启动了socket服务,用来作为服务器响应,当鉴别用户信息后,通过websocket连接到socket服务器,把必要的信息进行存储(包括聊天信息,用户信息等)。
3.在我实现的socket服务中,我对原本的websocket步骤进行了修改,我在上述的1和2步骤中添加了将数据发送到服务器这个步骤,与第三步的区别在于,一个是发送用户信息,一个是发送聊天信息,两者主要是利用type(1为用户信息,2为聊天信息)进行区分。
转存失败重新上传取消## 4.实现过程
4.1 首先是客户端主动连接Socket服务,同时将用户信息发送到socket服务器,并且开始监听服务器的消息
4.2 将聊天的信息发送到socket服务器,其他监听了该端口的设备在就会接收到服务器的反馈
4.3 关闭监听端口
## 5.其他
整个基本im聊天实现过程中,包括实体类的设计,逻辑的实现过程中都是进行了反复的尝试,重构,比如主界面左上角的头像就经过了几次的尝试和重构。
第一次实现思路是在socket建立连接的时候初始化数据,虽然这样的数据能保证唯一性,但是其他地方的调用就变得麻烦,例如主界面左上角的头像无法引用。
第二次改进思路是建造一个登录用户的实体类(Me),并且利用单例在实体类里初始化用户信息,这样就能全局引用了。但是这样有个弊端就是每次热重启,这个实体类(Me)就会重新初始化,那么跟我socket里的数据就发生了冲突
第三次尝试思路是第一次的基础上进行了改良,在初始化后将数据保存到登陆用户的实体类(Me)中,这样既能全局引用,又能保持唯一可用性。
但是这样实现又出现了一个小bug:如果清空本地SharedPreferences里的所有缓存数据,因为SharedPreferences进行的是异步操作,那么从整体的生命周期看,模拟器会先执行完所有的ui之后才会对用户进行初始化,所以我的主界面左上角一开始头像就是空的,只有当用户初始化结束后才会重新更新赋值,也就是说重启服务后头像会出现短暂的空白时间,这个在之后会想办法进行一个优化。
## 6.总结和反思
反复的重构意味着最初的设计并没有做的很好,在编码前的思考还不够彻底,才会在不断的完善过程中去修改和推翻之前的构思。包括接下来希望能在聊天中使用图片,视频流应该如何去实现,消息实体应该怎样去设计一开始都没能思考清楚,导致接下来可能又会进行一部分重构,这是在之后需要改善的。
## 7.最后
最后希望各位看官能给一些指导意见,你们的意见都是我改进的方向和动力.