iOS即时通信学习

阎宝
2023-12-01

socket简单的通信demo

首先,我要先了解下即时通信主要用到了哪些技术?

1.语音聊天模块

从技术上讲主要就是录音:把录音文件发到服务器,再从服务器传到另外一个设备进行播放,这个过程是非常简单的,但是考虑一个问题就是要适合网络传输,因为网络是特别脆弱的,不管是发的时候还是收的时候它会占到我们手机的流量,这个流量是大家比较关心的,因为这个网络确实太贵了,为了便于网络传输我们进行一个压缩和解压的过程,知道这个过程之后,我们可以进入我们iOS平台要讲的东西。第一个是语音录制、语音编解码、语音播放,还有Audaio Session还有语音实践。

在语音录制里面我们会讲哪几个,我们比较想了解就是IOS里面录制哪些语音格式,还有我们的API怎么去使用,还有录制的音量怎么样,录制的时候波浪会随着我们声音大小变换,这个是IOS也支持的。

我们看看iOS支持默认语音录制格式,他支持的格式不是很多,很多我们想要可能没有,但是我们可以给大家介绍基本的格式它是支持的AAC压缩比较高,效果比较好。还有ALAC,还有ILBC,这个用于网络传输的一个语音格式。IMA4这是一个压缩效率很高,但是各方面因为效率高了,可能别的算法、复杂度可能降一点,要求效率比较高考虑这种格式,还有LINEAR PCM,这个是无压缩的,还有U—LAW和ALAW。

刚开始,我先分析了一个简单的基于UDP的socket的在局域网内聊天的即时通讯项目,主要实现发送信息的功能

首先导入第三方库:AsyncUdpSocket.h,AsyncUdpSocket.m;IPAddress.h,IPAddress.c;

然后你了解一下UDP的socket通信的工作流程,见UDP Socket通信。

现在开始编写代码实现:

1.在通信开始前,先要获取自己设备的id,这是在三方库中已经封装好了的,可以直接使用:

NSString *ip_iphone = [selfdeviceIPAdress];

   self.myIP = ip_iphone;

//得到本机IP

-(NSString *) deviceIPAdress

{

    InitAddresses();

    GetIPAddresses();

    GetHWAddresses();

    return [NSStringstringWithFormat:@"%s",ip_names[1]];

}


2.然后就可以创建和调用UDP的socket连接了

-(void)openUDPServer

{

    //初始化udp

    self.udpSocket = [[AsyncUdpSocketalloc]initWithDelegate:self];

    //绑定端口

    [self.udpSocketbindToPort:8088error:nil];

    //发送广播设置

    [self.udpSocketenableBroadcast:YESerror:nil];

   //加入广播组,能接收群里其他客户端的消息

    [self.udpSocketjoinMulticastGroup:@"224.0.0.2"error:nil];

    //启动接收线程

    [self.udpSocketreceiveWithTimeout:-1tag:0];

}

注:DatagramSocket只允许数据报发送给指定的目标地址,而MulticastSocket可以将数据报以广播方式发送到数量不等的多个客户端。

若要使用多点广播时,则需要让一个数据报标有一组目标主机地址,当数据报发出后,整个组的所有主机都能收到该数据报。IP多点广播(或多点发送)实现了将单一信息发送到多个接收者的广播,其思想是设置一组特殊网络地址作为多点广播地址,每一个多点广播地址都被看做一个组,当客户端需要发送、接收广播信息时,加入到该组即可。

IP协议为多点广播提供了一批特殊的IP地址,下面列举几个常见的:

224.0.0.1 子网上的所有系统
224.0.0.2  子网上的所有路由器
224.0.0.12  dhcp服务器
224.0.1.1    ntp
224.0.1.24   wins服务器

3.UDP代理:socket开始接收数据

-(BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port

{

    [self.udpSocketreceiveWithTimeout:-1tag:0];

    NSLog(@"host -- >%@",host);

   //收到自己发的广播消息不显示

    NSMutableString *tempIP = [NSMutableStringstringWithFormat:@"::ffff:%@",self.myIP];

    if ([host isEqualToString:self.myIP] || [hostisEqualToString:tempIP])

    {

        return NO;

    }

   //接收到数据,在UITableView中显示出来

    NSString *info = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];

    NSLog(@"%@",info);

    [self.chatArrayaddObject:[NSDictionarydictionaryWithObjectsAndKeys:info,@"text",@"other",@"speaker"nil]];

    [self.tableViewreloadData];

    [self.tableViewscrollToRowAtIndexPath:[NSIndexPathindexPathForRow:[self.chatArraycount]-1inSection:0]

                         atScrollPosition:UITableViewScrollPositionBottom

                                  animated:YES];

//已经处理完毕

return YES;

}

以上就是聊天主要socket代码,其他的就是你要注意的细节问题,比如你的消息呈现是以tableView形式还是其他,当你点击编辑消息时,键盘出现,视图整体上移,编辑结束,再还原视图位置。当你消息发送出去后,数据保存形式,显示时的格式。如何根据屏幕显示的信息容量,计算当前tableView应该从那一行显示。
在开发过程中,会用到的一些方法:
(1)创建一个内容可拉伸,而边角不拉伸的图片,需要两个参数,第一个是左边不拉伸区域的宽度,第二个参数是上面不拉伸的高度。

UIImageView *bubbleImageView = [[UIImageViewalloc]initWithImage:[bubblestretchableImageWithLeftCapWidth:21topCapHeight:14]];

根据设置的宽度和高度,将接下来的一个像素进行左右扩展和上下拉伸。

注意:可拉伸的范围都是距离leftCapWidth后的1竖排像素,和距离topCapHeight后的1横排像素。

参数的意义是,如果参数指定10,5。那么,图片左边10个像素,上边5个像素。不会被拉伸,x坐标为11和一个像素会被横向复制,y坐标为6的一个像素会被纵向复制。

注意:只是对一个像素进行复制到一定宽度。而图像后面的剩余像素也不会被拉伸。
(2)根据字符串指定的宽度/高度内的实际高度/宽度,或者两者都限制情况下的size大小

CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(150.0f, 1000.0f)lineBreakMode:UILineBreakModeCharacterWrap];

延伸:获取字符串不折行显示时所需的长度:CGSize titleSize = [aString sizeWithFont:font constrainedToSize:CGSizeMake(MAXFLOAT, 30)];

获取字符串在指定长度内,所需的宽度:CGSize titleSize = [aString sizeWithFont:font constrainedToSize:CGSizeMake(60, MAXFLOAT)];

判断字符串是否需要折行的代码:

  1. CGSize sz = [label.text sizeWithFont:label.font                      

  2. constrainedToSize:CGSizeMake(MAXFLOAT, 40)]; 

  3. CGSize linesSz = [label.text sizeWithFont:label.font 

  4.                         constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT) 

  5.                             lineBreakMode:UILineBreakModeWordWrap]; 

  6.  

  7. if(sz.width <= linesSz.width) //判断是否折行

  8.     lastPoint = CGPointMake(label.frame.origin.x + sz.width, label.frame.origin.y); 

  9. else 

  10.     lastPoint = CGPointMake(label.frame.origin.x + (int)sz.width % (int)linesSz.width,linesSz.height - sz.height); 

(3)注意,别忽略了一句代码,他表示不限制文本折行,少了这句,你的文本全显示在一行上,

textLabel.numberOfLines = 0;


资源上传:http://download.csdn.net/download/u013929312/7600505


 类似资料: