IOS宿舍管理系统之CocoaAsyncSocket实现即时通信

一:下载第三库 终端中import “CocoaAsyncSoket”

二:
服务器(.h)文件中让外部调用

//单列模式
+(MyChatServer*)sharedServer;

//开启聊天服务器
-(void)startServer;

//发送信息
-(void)sendMsg:(NSString*)msg;

服务器端(.m)文件中:
1.导入:#import <GCDAsyncSocket.h>
2.实现代理:@interface MyChatServer()
3.
//创建服务器socket
@property(nonatomic,strong)GCDAsyncSocket * serverSocket;
//创建全球队列
@property(nonatomic,strong)dispatch_queue_t golbalQueue;

//保存当前的客户端clientSocket
@property(nonatomic,strong)GCDAsyncSocket * clientSocket;

//创建心跳
@property(nonatomic,strong)CADisplayLink *link;

4.确保单例:

+(MyChatServer*)sharedServer{
    if (instance == nil) {
        instance = [[MyChatServer alloc]init];
        //创建全局que
        instance.golbalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        //创建服务器的socket 注意这里的是初始化的同时已经制定了delegate
        instance.serverSocket = [[GCDAsyncSocket alloc]initWithDelegate:instance delegateQueue:instance.golbalQueue];
    }
    return instance;
}

5.启动服务器:

//开启服务器
-(void)startServer{
    //打开监听端口
    NSError * err;
    [_serverSocket acceptOnPort:12345 error:&err];
    if (!err) {
        NSLog(@"服务器开启成功");
    }else{
        NSLog(@"服务器开启失败");
    }
}

6.发送信息

//发送信息  心跳
-(void)sendMsg: (NSString*)msg{
    NSData *sendData = [msg dataUsingEncoding: NSUTF8StringEncoding];
    [_clientSocket writeData:sendData withTimeout:-1 tag:100];
}

//发送心跳
-(void)heartBeat{
    [self sendMsg:@""];
}

---------------实现代理-------------------
7.客户链接时调用这个代理

-(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket{
    //sock为服务器的socket,服务器端的socket只负责客户端的链接,不负责数据的读取
    //newSocket为客户端的socket
    _clientSocket = newSocket;
    //NSLog(@"客户端的socket %p 服务器端的socket %p",newSocket,sock);
    //newSocket为客户端的socket,这里读取数据
    [newSocket readDataWithTimeout:-1 tag:100];
    //这也要心跳
    _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(heartBeat)];
    _link.preferredFramesPerSecond = 1;
    [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

8.服务器写数据给客户端时调用

-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
    //[sock readDataWithTimeout:-1 tag:100];
    [_clientSocket readDataWithTimeout:-1 tag:100];
}

9.接收客户发过来的数据时调用

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    //sock为客户端的socket
    //NSLog(@"客户端的socket %p",sock);
    //接收的数据
    NSString * receiverStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    if (receiverStr.length == 0) {
        NSLog(@"这是对方的心跳粘包%@",receiverStr);
    }else{
        //发送一个数据来了的消息
        NSLog(@"他的消息%@",receiverStr);
        [[NSNotificationCenter defaultCenter]postNotificationName:kOthertMessageDidComeNotify object:receiverStr];
    }
}

///

二.服务器(.h)文件中让外部调用

+(MyChatClient*)sharedClient;

-(void)connectServer; 

-(void)sendMsg: (NSString*)msg;

服务器.m实现文件

1.属性

//创建客户端socket
@property(nonatomic,strong)GCDAsyncSocket * socket;
//心跳
@property(nonatomic,strong)CADisplayLink *link;
//服务端
@property(nonatomic,strong)GCDAsyncSocket * serverSocket;

2.单例

+(MyChatClient*)sharedClient{
    if (instance == nil) {
        instance = [[MyChatClient alloc]init];
    }
    return instance;
}

3.链接服务器

- (void)connectServer{
    //1.主机与端口号
    NSString *host = @"192.168.43.85";
    int port = 12345;
    
    //初始化socket,这里有两种方式。分别为是主/子线程中运行socket。根据项目不同而定
    _socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];//这种是在主线程中运行
    //_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; 这种是在子线程中运行
    
    //开始连接
    NSError *error = nil;
    [_socket connectToHost:host onPort:port error:&error];
    if(error) {
        NSLog(@"error:%@", error);
    }
    
}

4.发送信息和心跳

//发送聊天数据
-(void)sendMsg: (NSString*)msg{
    NSData *sendData = [msg dataUsingEncoding: NSUTF8StringEncoding];
    [_socket writeData:sendData withTimeout:-1 tag:201];
    [_serverSocket readDataWithTimeout:-1 tag:100];
}

//发送心跳
-(void)sendHeart{
    //发送心跳
    [self sendMsg:@""];
}

实现代理
5.与服务器链接成功时调用

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
    //保存这个服务器端的socket
    _serverSocket = sock;
    
    //链接成功
    NSLog(@"链接成功");
    
    //发送心跳
    _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(sendHeart)];
    _link.preferredFramesPerSecond = 0.1;
    [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

6.链接断开时调用

//断开链接
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    if (err) {
        NSLog(@"链接失败");
    }else{
        NSLog(@"正常断开");
    }
}

7.数据发送成功时调用

//数据发送成功
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
    //发送完数据手动读取
    [sock readDataWithTimeout:-1 tag:tag];
}

8.读取到服务器发过来的数据

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    //代理在子线程/主线程中使用
    NSString * receiveStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    
    
    if (receiveStr.length == 0) {
        //这是n个@“”的粘包
    }else{
        //这是真正的数据
        //发送一条得到数据的消息
        [[NSNotificationCenter defaultCenter]postNotificationName:kOthertMessageDidComeNotify object:receiveStr];
    }
}


四、备注:仿QQ微信聊天界面 用UITabelView 配个 Bmob云端即可即可实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值