即时通讯(III)
即时通讯的开源库
目前及时通讯可以使用环信、柔云、腾讯云,这些都是基于TCP连接的,UI也是高度定制的,而且它们的技术也是比较成熟的。
XMPP比较早,是开源的,但是坑也比较多。传输的数据是XML,造成了很多流量的雍余。
数据格式
Socket通讯报文是没有结束标识的,通讯报文保留前8个字节的,给我们字节扩展用的。可以利用这前八个字节做些事情。比如:
我们传一个图片,首先要知道它怎么结束,可以给他一个结束标识,如,“/n/n”。第一个4字节我们可以把图片的总长度传过去,根据这个长度判断ImageDate是否传完。第二个字节可以传它的数据格式,定义为content,用来告诉客户端和服务器端传的是什么。然后再拼接为ImageData,并传送到Action。
代码Demo
#import "ViewController.h"
#import "GCDAsyncSocket.h" static NSString *server_host = @"127.0.0.1";
static const short server_port = ; #define VA_Commadn_id 0x00000001 @interface ViewController ()<GCDAsyncSocketDelegate> @property (strong, nonatomic) GCDAsyncSocket *clientSocket;
@property (weak, nonatomic) IBOutlet UITextField *textField; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initGCDAsyncSocket];
} - (void)initGCDAsyncSocket{
//创建 Socket
if (_clientSocket == nil) {
_clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self
delegateQueue:dispatch_get_main_queue()];
}
} - (BOOL)connect{
NSError *error = nil;
BOOL connectFlag = [_clientSocket connectToHost:server_host onPort:server_port error:&error];
if (error) {
NSLog(@"%@",error);
}
return connectFlag;
} - (void)disConnect{
[_clientSocket disconnect];
} #pragma mark -- GCDAsyncSocketDelegate
//连接成功回调
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
NSLog(@"连接成功"); [_clientSocket readDataWithTimeout:- tag:];
} //断开连接
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
NSLog(@"断开连接%@",err.localizedDescription);
} //接受消息
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
NSLog(@"接受到消息");
[_clientSocket readDataWithTimeout:- tag:];
} - (void)sendImage{
//图片数据
UIImage *img = [UIImage imageNamed:@"icon_socket"];
NSData *imgData = UIImagePNGRepresentation(img); NSMutableData *totalData = [NSMutableData data]; //0~3 总长度,前四个字节的总长度 unsigned int totalSize = (int)imgData.length + + ; NSData *totalSizeData = [NSData dataWithBytes:&totalSize length:];
//数据拼接
[totalData appendData:totalSizeData]; // 拼接标识
unsigned int commandId = VA_Commadn_id; NSData *commandIdData = [NSData dataWithBytes:&commandId length:]; [totalData appendData:commandIdData]; //拼接图片数据
[totalData appendData:imgData]; //发送数据
[_clientSocket writeData:totalData withTimeout:- tag:]; } #pragma mark -- Button Action - (IBAction)connectAction:(UIButton *)sender{
[self connect];
} - (IBAction)disConnectAction:(UIButton *)sender{
[self disConnect];
} - (IBAction)sendAction:(UIButton *)sender{
NSData *data = [_textField.text dataUsingEncoding:NSUTF8StringEncoding]; [_clientSocket writeData:data withTimeout:- tag:];
} - (IBAction)sendImageAction:(id)sender {
[self sendImage];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end
使用的第三方库的Podfile:
platform:ios, '9.0' target "002--AsyncSocket" do
pod 'CocoaAsyncSocket'
end
及时通讯绘制图片
即时通讯通过画板来绘图可以将绘制贝塞尔尔曲线的CGPoint点放入一个数组,但是CGPoint点是不能传递过去的,会崩溃的。可以将CGPoint点转化为字典,再传递过去。
心跳机制
简介:
在使用TCP长连接的IM服务设计中,往往都会涉及到心跳。心跳一般是指客户端每隔一定时间向服务端发送自定义指令,以判断双方是否存活,因其按照一定间隔发送,类似于心跳,故称为心跳指令。
003--WebSocket 即时通讯机制 代码片段
- (void)initHeart{
//keepAlive 保证连接存在, 真正可用的 心跳机制验证连接双方是否可用
//心跳包 ------ > 连接双方不可用,主动断开连接
//服务端也是会有,心跳包,主动断开连接
//设置超时间 3分钟(心跳设置3分钟):是因为NAT(与外网和内网有关)的失效时间是3分钟
__weak typeof(self) weakSelf = self;
_heatBeat = [NSTimer scheduledTimerWithTimeInterval:* repeats:YES block:^(NSTimer * _Nonnull timer) {
//具体发送根据实际情况
[weakSelf.socket send:@"heart"];
}];
[[NSRunLoop currentRunLoop] addTimer:_heatBeat forMode:NSRunLoopCommonModes];
}
Ping-Pong 机制
发送消息时会判断连接是否存在。如:
A设备给B设备发送消息,A设备上线他会告诉B设备A设备上线了,会得到服务器的反馈,知道A设备上线了。A设备把数据包丢给B设备,B设备会检测A设备是否在线,如果在线,他会通过A和B之间建的Socket连接发送消息,若B不在线,会走苹果的APNS通道。
WebSocket协议(数据帧格式)
即时通讯(III)的更多相关文章
- 利用WCF双工模式实现即时通讯
概述 WCF陆陆续续也用过多次,但每次都是浅尝辄止,以将够解决问题为王道,这几天稍闲,特寻了些资料看,昨晚尝试使用WCF的双工模式实现了一个简单的即时通讯程序,通过服务端转发实现客户端之间的通讯.这只 ...
- android环境下的即时通讯
首先了解一下即时通信的概念.通过消息通道 传输消息对象,一个账号发往另外一账号,只要账号在线,可以即时获取到消息,这就是最简单的即使通讯.消息通道可由TCP/IP UDP实现.通俗讲就是把一个人要发送 ...
- 【原创】轻量级即时通讯技术MobileIMSDK:Android客户端开发指南
申明:MobileIMSDK 目前为个人维护的原创开源工程,现陆续整理了一些资料,希望对需要的人有用.如需与作者交流,见文章底签名处,互相学习. MobileIMSDK开源工程的代码托管地址请进入 G ...
- 【原创】轻量级移动设备即时通讯技术MobileIMSDK的常见问题解答
申明:MobileIMSDK 目前为个人原创开源工程且已发布,现整理了一些有关MobileIMSDK的常见的问题,希望对需要的人有用,谢谢.如需与作者交流,见文章底部个人签名处,互相学习. Mobil ...
- 【原创】轻量级移动端即时通讯技术 MobileIMSDK 发布了
申明:MobileIMSDK目前为个人原创开源工程,投入了大量的时间和精力,希望对需要的人有所帮助.如需与作者交流,见文章底部个人签名处,互相学习.Q群:215891622,欢迎共同志趣者学习和交流. ...
- ActiveMQ 即时通讯服务 浅析
一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provi ...
- APP邂逅即时通讯云,让你的手机APP聊起来
#推荐活动# #线下沙龙# 明天下午在IC咖啡 —— <APP邂逅即时通讯云,让你的手机APP聊起来>, http://url.cn/Y8sYo5
- 岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯
岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯 看过了QQ和360斗争的开端高潮,当然现在还不能说这场斗争已经结束,在我看来这次的事件未尝不是一个适 ...
- Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
1. 前言 Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Serve ...
随机推荐
- spring-boot-actuator报错Full authentication is required to access this resource
解决办法[设置端点访问 ]: 1, 关闭验证 management.security.enabled=false 2,开启HTTP basic认证 - 添加依赖 <dependency> ...
- 【分布式系列】session跨域及单点登录解决方案
Cookie机制 Cookie技术是客户端的解决方案,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息. ...
- 如何在spring-boot web项目中启用swagger
swagger的三个项目及其作用 我们打开swagger的官网,会发现有三个swagger相关的项目,它们分别是 swagger-editor 作用是通过写代码,生成文档描述(一个json文件或其他格 ...
- [Sublime] Sublime Text 3126 lincense
—– BEGIN LICENSE —– Michael Barnes Single User License EA7E- 8A353C41 872A0D5C DF9B2950 AFF6F667 C45 ...
- kaggle竞赛-保险转化-homesite
时间格式的转化 查看数据类型 查看DataFrame的详细信息 填充缺失值 category 数据类型转化 模型参数设定 结论 该项目是针对kaggle中的homesite进行的算法预测,使用xgbo ...
- PHP删除数组中空值的方法
- linux的基本操作(NFS服务配置)
服务配置 [什么是NFS] NFS会经常用到,用于在网络上共享存储.这样讲,你对NFS可能不太了解,笔者不妨举一个例子来说明一下NFS是用来做什么的.假如有三台机器A.B.C,它们需要访问同一个目录, ...
- DCL并非单例模式专用
我相信大家都很熟悉DCL,对于缺少实践经验的程序开发人员来说,DCL的学习基本限制在单例模式,但我发现在高并发场景中会经常遇到需要用到DCL的场景,但并非用做单例模式,其实DCL的核心思想和CopyO ...
- elk-filebeat-(效果图示)(四)
一.vim filebeat-6.3.2-linux-x86_64/filebeat.yml - type: log # Change to true to enable this input con ...
- js获取谷歌浏览器版本 和 js分辨不同浏览器
// 获取谷歌版本 function getChromeVersion() { var arr = navigator.userAgent.split(' '); var chromeVersion ...