通过socket实现服务端与客户端的长连接,达到实时监听客户端状态、实时保持客户端和服务端连接,数据传输等等的目的,可能有以下几种叫法:1.长连接 2.心跳包的实现 3.单点登录(APP同一账号同时登录一个设备)。。。
因为项目遇到单点登录部分,所以本文实现的是第三点,如有其他需求,修改,调整一下代码即可...
FIRST.先说服务端的部分:
1.创建工程,如下图
2.代码结构
3.再说两个主要类,ZJJSocketService
.h 中 :
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
@interface ZJJSocketService : NSObject
//开启服务
- (void)start;
@end
#import "ZJJSocketService.h"
@interface ZJJSocketService ()<GCDAsyncSocketDelegate>
@property (strong,nonatomic) GCDAsyncSocket *socket;
@property (strong,nonatomic) NSMutableArray *clientSockets;//保存客户端scoket
@end
@implementation ZJJSocketService
- (NSMutableArray *)clientSockets
{
if (_clientSockets ==nil) {
_clientSockets = [[NSMutableArrayalloc]init];
}
return_clientSockets;
}
- (void)start
{
//1.创建scoket对象
GCDAsyncSocket *serviceScoket = [[GCDAsyncSocketalloc]initWithDelegate:selfdelegateQueue:dispatch_get_global_queue(0,0)];
//2.绑定端口(9999)
//端口任意,但遵循有效端口原则范围:0~65535,其中0~1024由系统使用或者保留端口,开发中建议使用1024以上的端口
NSError *error =nil;
[serviceScoket acceptOnPort:9999error:&error];
//3.开启服务(实质第二步绑定端口的同时默认开启服务)
if (error ==nil)
{
NSLog(@"开启成功");
}
else
{
NSLog(@"开启失败");
}
self.socket = serviceScoket;
}
#pragma mark GCDAsyncSocketDelegate
//连接到客户端socket
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
//sock 服务端的socket
//newSocket 客户端连接的socket
NSLog(@"%@----%@",sock, newSocket);
//1.保存连接的客户端socket(否则newSocket释放掉后链接会自动断开)
[self.clientSocketsaddObject:newSocket];
//连接成功服务端立即向客户端提供服务
NSMutableString *serviceContent = [NSMutableStringstring];
[serviceContent appendString:@"话费查询请按1\n"];
[serviceContent appendString:@"话费充值请按2\n"];
[serviceContent appendString:@"投诉建议请按