服务层 |
ChatModel |
负责处理聊天的本地数据库入库与服务器通信问题 |
(-(void)requestClearNewMessage:(ChatRoom *)room; |
发送请求清空对应房间的新消息,主要是进入房间时调用 |
messgeIdArr |
获取到的消息数组,有可能本地正在存,服务器又推过来了,用来过滤掉这种情况 |
|
|
请求需要手动调用,本地化会自动处理 |
(-(void)requestDeleteRoom:(NSString *)roomId; |
发送请求删除房间,后台删除,与本地数据库无关,本地数据库是直接删除的 |
dataSource |
当前用户的房间列表,对象数组,内部存储的是chatRoom,外部可以直接获取 |
|
|
请求的回调全部采用通知,具体看每个通知代表什么意思,请自行百度翻译或看通知的注释 |
(-(void)requestRoomList:(NSString *)roomId; |
获取房间列表,回调会自动本地化,如果传了roomId就是获取某个,没传就是获取整个房间列表 |
saveSource |
要保存的房间列表,入库时使用,外部尽量不要调用该属性 |
|
|
|
(-(void)startRePostMessageQueue; |
启用重发队列,会自动在socket连接的时候启动,如果重发数组有值会进行重发 |
restArr |
重发数组,里面是完整的消息信息,包括wsStr属性 |
|
|
|
(-(void)logoOut; |
退出登录时调用,清空聊天的所有数据信息 |
requestRooms |
正在请求的roomId数组,用来防止同一时间对一个房间信息进行重发拉取,请求成功会自动移除roomId |
|
|
|
(-(void)uploadImage:(UIImage *)image packId:(NSString *)packId localInfo:(NSDictionary *)localInfo localStr:(NSString *)imagePath roomId:(NSString *)roomId; |
上传图片给服务器 |
chatingRoomId |
用户正处在的房间室的ID,用来判断用户是否在某个聊天室 |
|
|
|
(-(void)uploadVoice:(NSString *)filename length:(NSString *)passTimeStr packid:(NSString *)packId roomId:(NSString *)roomId; |
上传音频给服务器 |
unReadCount |
未读消息个数,重写get方法实现,可以直接获取个数 |
|
|
|
(-(void)repushMessage:(NSDictionary *)dic; |
手动启用重发某条消息 |
wsConnet |
websocket是否连接,可以获取sokect的连接状态 |
服务层 |
appdelegate |
这里仅仅列出appdelegate中的聊天部分 |
(- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message |
所有socket请求的回调 |
_webSocket |
socket对象,用来开启关闭重连socket |
|
|
appdelegate中的方法主要是获取到服务器的反馈,然后通过通知与本地的数据通信 |
(- (void)timerRun:(NSTimer *)timer |
用来重连socket服务器 |
|
|
|
|
socket的启动顺序大致是:1、通过webSocketDidOpen方法连接socket服务器,并登录用户2、正常情况下,每10秒进行一次ping、pong的通信,已确保用户是否在线3、socket的所有请求都将在didReceiveMessage方法中回调,根据type判断socket是哪种方法的回调,如果同时进行同样的操作,可传递packid给服务器,不论成功失败,服务器将返回packid |
(- (void)webSocketDidOpen:(SRWebSocket *)webSocket |
连接socket服务器,会传用户的auto_token等信息给服务器进行登录 |
|
|
|
|
新消息可能会存在重复的情况,在didReceiveMessage方法中需要进行本地数据库是否存在该条聊天信息的判断 |
|
|
|
|
|
|
新消息振东的情况是用户不在该消息对应的聊天室,该聊天信息不存在于本地数据库 |
|
|
|
|
服务层 |
SWConstant.h |
主要进行通知名称所对应的意思进行列举 |
|
|
|
|
|
|
|
|
|
|
|
view/layout视图层 |
ChatCellLayout |
高度计算、布局、获取资源 |
(- (instancetype)initWithModel:(ChatMessage *)message isGroup:(BOOL)isGroup avatar:(NSString *)avatar |
初始化方法,需要传递聊天模型、是否是群组回话、头像地址 |
message |
聊天信息模型 |
|
|
作用:1、对聊天气泡的内容进行高度计算2、根据附件的id从服务器获取附件的地址3、计算气泡中所有控件的高度与布局 |
(-(void)configMessageImgSize |
刷新图片的高度 |
cellHeight |
气泡对应的cell整体高度 |
|
|
特点:整个cell的高度只用计算一次,极大优化了tableviewcell高度计算的性能;有图片的cell的高度在获取到地址之前无法确定,导致会有个默认的正方形蓝色气泡 |
|
|
type |
消息的类型 |
|
|
|
|
|
isMine |
是否是自己发送的消息 |
|
|
|
|
|
uname |
发送者的uname |
|
|
|
|
|
contentHeigh |
内容的高度(文字、图片、名片、位置) |
|
|
|
|
|
timeHeight |
时间戳的高度 |
|
|
|
|
|
contentWidht |
消息的宽度,不足一行时会用到 |
|
ChatCell |
聊天的cell,做视图的展示,以及几个简单的回调 |
(-(void)rePushMessage:(ChatMessage *)message; |
重发消息代理 |
playingId |
正在播放音频的cellID用来关闭播放 |
|
|
|
|
|
progress |
图片上传的进度,会根据通知进行刷新 |
|
|
|
|
|
|
|
业务逻辑层 |
ChatDetailListSwVC |
聊天详情控制器,包含底部的几个控件、以及复杂的cell发送规则、重发规则、获取最新消息等 |
(-(void)requestChatData:(BOOL)toBack |
请求聊天消息的方法,toBack等于NO代表向前获取最新的消息,反之向后获取老的消息历史记录 |
audioPlayer |
音频播放器、需要注意在视图appear与disappear时进行代理的销毁与创建 |
|
|
VC中会进行一定的本地数据库逻辑处理。但主要是进行数据和界面的刷新控制,以及消息的监听 |
(-(void)updateImgeCellProgress:(NSNotification *)noti |
图片上传进度的回调,object内带的数据有消息的packid和进度的百分比 |
imagesArr |
已经加载出来的聊天信息的图片数组,用来播放聊天室内的所有图片 |
|
|
|
(-(void)reloadCellNotif:(NSNotification *)noti |
刷新本地的某条消息 |
chatToolbarView |
聊天的底部工具栏 |
|
|
|
(-(void)getLastestMessagesReload:(NSNotification *)noti |
得到了消息列表的回调 |
chatToolbarExpressionView |
聊天表情栏 |
|
|
|
(-(void)getNewMessage:(NSNotification *)noti |
获得新消息 |
chatToolbarMoreView |
聊天的更多视图 |
|
|
|
(-(void)sendMessageFeedBack:(NSNotification *)noti |
发送消息的回调,失败会有packid传回来,这里只处理界面的展示,具体本地入库的逻辑在chatDBHelper处理 |
_forwardMessageId |
聊天室向前获取信息的id,也就是最新的从服务器获取回来的消息的id |
|
|
|
(-(void)sendDataWithType:(NSString *)type andContent:(NSString *)content andImageDic:(NSDictionary *)imageDic packId:(NSString *)packId |
发送消息方法;需要注意,文字和名片默认是发送成功,且未在发送中,这样做是为了避免界面上显示菊花的转动动画 |
_lastMessageId |
向后查看聊天记录的消息id,也就是界面上最上面最老的消息的id |
|
|
|
(-(void)scrollViewDidScroll:(UIScrollView *)scrollView |
列表滚动到顶部,自动进入刷新状态,体验的优化 |
|
|
|
ChatDBHelper |
本地数据库的增删改查,数据库主要有两个表,一个是聊天室表,每个用户根据uid创建了不同的表名;而聊天消息表是一个表,每个用户可以根据自己所拥有的房间号去查询对应的聊天信息;此外还有一个用户信息表,用来保存聊天中简单的用户数据,如头像、用户名、id等,减少获取用户头像的时间 |
(+(NSArray *)readMessagelists:(NSString *)roomId mId:(NSString *)lastMessageId; |
查询本地对应房间的消息;每次返回10条,如果是本地加载更多,需要传lastMEssageId;在这个方法中也进行了是否显示时间的判断;获取回来的是消息对象数组 |
roomid |
房间id |
|
|
消息表:roomid房间id;messageid消息id,在未发送成功的时候同localid、mtime一致,发送成功会更新为服务器返回id;mtime同messageid逻辑,消息的发送时间;localid本地的消息id;nosend消息未发送,1是未发送,0是发送;message消息体,包含消息的所有数据 |
(+(void)updateMessages:(id)message; |
更新某条消息 |
messageid |
消息id,在未发送成功的时候同localid、mtime一致,发送成功会更新为服务器返回id |
|
|
|
(+(void)saveMessage:(id)message; |
保存某条消息 |
mtime |
同messageid逻辑,消息的发送时间; |
|
|
|
(+(void)deleteMessagetTable:(NSString *)roomId; |
删除某房间的所有消息,对应界面的清空操作 |
localid |
本地的消息id; |
|
|
房间室表:roomId、room、mtime;同上,但是roomId是大写的 |
(+(ChatMessage *)readMessageById:(NSString *)messageId; |
读取一个消息对象 |
nosend |
消息未发送,1是未发送,0是发送; |
|
|
|
(+(void)deleteMessagetByMessageId:(NSString *)messageId; |
删除某条消息 |
message |
消息体,包含消息的所有数据,是一个jsonstring |
|
|
|
(+(NSArray *)readNosendMessagelists; |
读取未发送的消息列表 |
roomId |
房间室表的房间id |
|
|
|
(+(void)updateMessage:(id)message byLocalId:(NSString *)localId; |
在消息从未发送状态更新为发送状态,这里面主要涉及到一个本地消息id |
mtime |
房间室的最后一条消息的时间 |
|
|
|
(+(void)updateMessages:(NSArray *)arr StateSending:(BOOL)sending |
更新消息的发送状态 |
room |
房间室的数据,jsonstring |
|
|
宏的解释:#define RePushTime 5//重发等待的时间s#define ShowTimeLong 120//间隔时间#define RefreshWaitTime 12//刷新等待时间 |
(+(ChatRoom *)readChatRoom:(NSString *)roomId; |
读取聊天室的信息 |
|
|
|
|
|
(+(NSArray *)readChatRoomList; |
读取聊天室列表,返回是聊天室对象 |
|
|
|
|
|
(+(void)saveChatRoom:(ChatRoom *)room; |
保存聊天室房间 |
|
|
|
|
|
(+(void)saveChatRoomList:(NSArray *)roomList; |
保存列表 |
|
|
|
|
|
(+(void)deleteRoom:(NSString *)roomId; |
删除某个房间 |
|
|
|
|
|
(+(void)clearRoomList; |
清空整个聊天室列表 |
|
|
|
|
|
(+(void)updateChatRoom:(NSString *)roomId room:(NSDictionary *)room; |
更新房间室信息 |
|
|