iOS即时通讯(IM)

iOS即时通讯-系统Socket

2018-08-23  本文已影响68人  肖旭晖

首先要明白如何才能通信网络编程三要素:IP/端口号/协议

/*
创建全局的输入输出流,并且配置代理
*/
@interface SocketStream ()<NSStreamDelegate>
@property (nonatomic, strong) NSInputStream *inputStream;//输入流
@property (nonatomic, strong) NSOutputStream *outputStream;//输出流
@end

#pragma mark - 连接到主机
-(void)connectToHost{
    
    //设置流的配置信息
    NSString *host = HOST;
    uint32_t port  = PORT;
    
    //定义C语言的输入输出流
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    
    //与主机进行配对
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
    
    //C语音输入输出流转换成OC输入输出流
    self.inputStream = (__bridge NSInputStream *)(readStream);
    self.outputStream = (__bridge NSOutputStream *)(writeStream);
    
    //设置输入输出流代理
    self.inputStream.delegate = self;
    self.outputStream.delegate = self;
    
    //把输入输入流添加到主运行循环
    [self.inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [self.outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
    //打开输入输出流
    [self.inputStream open];
    [self.outputStream open];
}

#pragma mark - NSStreamDelegate
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
    
    switch (eventCode) {
        case NSStreamEventOpenCompleted:
            NSLog(@"输入输出流打开完成");
            break;
            
        case NSStreamEventHasBytesAvailable:
            NSLog(@"有字节可读");
            //读取数据
            [self readData];
            break;
            
        case NSStreamEventHasSpaceAvailable:
            NSLog(@"可以发送字节");
            break;
            
        case NSStreamEventErrorOccurred:
            NSLog(@"连接出现错误");
            break;
            
        case NSStreamEventEndEncountered:
            NSLog(@"连接结束");
            [self disconnect];
    
            break;
            
        default:
            break;
    }
}
#pragma mark - 读取输入流服务器返回时调用代理方法中的数据
-(void)readData{

    //建立一个缓冲区 可以放1024个字节
    uint8_t buf[1024];
    //返回实际装的字节数
    NSInteger len = [self.inputStream read:buf maxLength:sizeof(buf)];
    //把字节数组转化成字符串
    NSData *data =[NSData dataWithBytes:buf length:len];
    //从服务器接收到的数据
    NSString *reciveString =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    [self receiveMessage:reciveString];
}

#pragma mark - 接收数据
-(void)receiveMessage:(NSString *)message{
    NSLog(@"接收消息啦:%@",message);
}
#pragma mark - 发送数据
-(void)sendMessage:(NSString *)message{
    
    NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
    [self.outputStream write:data.bytes maxLength:data.length];
}

例如:

/*
xmpp的一个消息包 其中:
form:这个消息来自谁
to:这个消息发给谁
type:消息的类型(chat:单聊、room:群聊)
body:消息体
*/
<message from="zhangsan@www.baidu.com" 
         to="lisi@www.baidu.com"
         type="chat">
    <body>你好!</body>
    <active xmlns="http://jabber.org/protocol/chatstates"/>
</message>

这里的消息格式我们不限于xml、json和后台约定好

#pragma mark - 断开连接,并且把输入输出流从主运行循环中移除
-(void)disconnect{
    
    [self.inputStream close]
    [self.outputStream close];
    [self.inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [self.outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

demo:https://github.com/xiaoxuhui1024/iOS-SystemSocket

上一篇 下一篇

猜你喜欢

热点阅读