iOS 基于WebSocket
为了解决服务器不能主动向客户端推消息只能通过轮询来获取实时消息的弊端,WebSocket 就是这样发明的。
websocket的封装有很多 这里选择了facebook的socketrocket(gihub)
websocket是基于连接的 我们还需要一个服务器 这里选了Node.js
安装nodejs
brew install node
检测版本
node -v
node是依赖package.json安装依赖包的 刚创建还没有任何动西 可以先这样:
npm install express --save(yarn add express)
npm install ws(yarn add ws)
npm install hashmap(yarn add hashmap)
包依赖安装完后可以查看下package.json就可以了解他的作用了(类似Podfile)
创建js文件
WebSocket都是基于连接的,也就是说我们知道data是从那个connection发过来,但并不知道使用客户端的是a或者b,此时我们就需要在Server端能够标识用户身份和连接的对应关系。
需要在客户端连接到WebSocket之后,紧接着再发一次请求,告诉Server我的user_id是多少,Server将此user_id与connection之间的关系存储在hashmap中,至此就建立了chatId与connection的对应关系。当需要发送消息给对应的客户端,从此hashmap中取出对应用户的connection信息,调用其send方法发出消息即可。
node index.js执行js文件
至此服务端基本介绍完毕
客户端
1.首先要建立连接
[[SRWebSocket alloc] initWithURLRequest:request];
2.既然是基于连接的,就需要每个用户有一个对应的连接,根据一个表示找到对应的连接,给用户推送消息,这一步一般应该叫登陆操作
这一步需要让服务器知道你的登陆id,因为是测试,没有做密码的逻辑,发送消息也是根据这个登陆id来发送
3.发送消息
和登陆操作基本是相同的,但是可能需要多一些字段来区分不同类型的消息,比如图片消息,需要获取到图片地址在从网络请求图片。这里也写了一个直接发送图片二进制流的操作,代码如下
UIImage*image = [UIImageimageNamed:@"22.jpg"];
NSString*imageString =
[UIImageJPEGRepresentation(image, 1) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
[[JSRManager sharedInstance] sendMessage:@{@"content":imageString,
@"to":_sendToId.text,
kMsgType:JSRSendMsg}];
先将图片转成NSData,再通过base64编码成字符串方便客户端使用。
4.socketrocket提供和很多代理,我们可以用代理来获取很多状态消息
- (void)webSocket:(SRWebSocket*)webSocket didFailWithError:(NSError*)error
连接失败,这个时候我们就可以调用重连的方法
5.退出连接
// 退出聊天
ws.on('close', function(close) {
console.log('退出连接了',userConnectionMap);
if (objMessage == null) {
userConnectionMap.remove(objMessage['chatId']);
-- connectNum;
}
});这时候服务端需要从连接池把对应的连接删除掉。
补充:视频聊天部分关键知识点(https://www.jianshu.com/p/fb78ee430949)
最后附上代码地址(github)