SocketRocket --- iOS使用篇

开篇语:

很久以前使用的即时通讯工具SocketIO,由于其对websocket进行了深度的封装,它的协议已经变得很复杂,对于大多数开源的Java服务器代码是不兼容的。so,还是回归最原汁原味的websocket类库:SocketRocket 吧!

这个库由Facebook公司开源,可靠性还是有保障的。最近发布的版本是0.5.1,可以通过cocoapods安装。但是,未发布的代码显示,新的文件结构已经大量重构,文件数量大大增加(主要是把先前的功能拆分成了多个文件),同时修复了不少bug。所以,我建议还是直接下载源码,手动把源码导入到工程中。

接下来的代码也都是基于最新的GitHub源码写的,如果对0.5.1版本有冲突,还请抱歉。

使用:

SocketRocket虽然支持的功能非常全面,但是,例如心跳包发送、断线重连还需要自己实现。上代码:

HXSocketManager.h

#import

typedefenum: NSUInteger {

    HXSocketStatusConnecting,      // 正在连接

    HXSocketStatusConnected,      // 已连接

    HXSocketStatusFailed,          // 失败

    HXSocketStatusClosedByServer,  // 系统关闭

    HXSocketStatusClosedByUser,    // 用户关闭

    HXSocketStatusReceived,        // 接收消息

} HXSocketStatus;

@interfaceHXSocketManager :NSObject

/**

 重连时间间隔,默认3秒钟

 */

@property(nonatomic, assign) NSTimeInterval overtime;

/**

 重连次数,默认无限次 -- NSUIntegerMax

 */

@property(nonatomic, assign) NSUInteger reconnectCount;

/**

 当前链接状态

 */

@property(nonatomic, assign) HXSocketStatus status;

+ (instancetype)sharedInstance;

/**

 开始连接

 */

- (void)connect;

/**

 关闭连接

 */

- (void)close;

/**

 发送一条消息

 @parammessage 消息体

 */

- (void)sendMessage:(NSString*)message;

@end

HXSocketManager.m

#import "HXSocketManager.h"

#import "SRWebSocket.h"

@interface HXSocketManager ()

@property(nonatomic, strong) SRWebSocket *webSocket;

@property(nonatomic, weak) NSTimer *timer;

@property(nonatomic, strong) NSTimer *pingTimer;  //每10秒钟发送一次ping消息

@property(nonatomic, strong) NSString *urlString;

@property(nonatomic, assign) NSUInteger currentCount;  //当前重连次数

@end

@implementation HXSocketManager

+ (instancetype)sharedInstance {

    static dispatch_once_t onceToken;

    static HXSocketManager *instance = nil;

    dispatch_once(&onceToken,^{

        instance = [[super allocWithZone:NULL] init];

        instance.overtime = 3;

        instance.reconnectCount = NSUIntegerMax;

        instance.urlString = WSUrl;


        // 开启ping定时器

        instance.pingTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:instance selector:@selector(sendPingMessage) userInfo:nil repeats:YES];

        [[NSRunLoop currentRunLoop] addTimer:instance.pingTimer forMode:NSRunLoopCommonModes];

    });

    return instance;

}

+ (id)allocWithZone:(struct _NSZone *)zone{

    return [self sharedInstance];

}

/**

开始连接

*/

- (void)connect {

    //先关闭

    [self.webSocket close];

    self.webSocket.delegate = nil;


    //后开启

    self.webSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlString]]];

    self.webSocket.delegate = self;

    self.status = HXSocketStatusConnecting;

    [self.webSocket open];

}

/**

关闭连接

*/

- (void)close {

    [self.webSocket close];

    self.webSocket = nil;


    [self.timer invalidate];

    self.timer = nil;

}

/**

重新连接

*/

- (void)reconnect {


    if (self.currentCount < self.reconnectCount) {

        //计数器+1

        self.currentCount ++;

        NSLog(@"%lf秒后进行第%zd次重试连接……",self.overtime,self.currentCount);

        // 开启定时器

        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:self.overtime target:self selector:@selector(connect) userInfo:nil repeats:NO];

        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

        self.timer = timer;

    }

    else{

        NSLog(@"重连次数已用完……");

        if (self.timer) {

            [self.timer invalidate];

            self.timer = nil;

        }

    }

}

/**

发送一条消息

@param message 消息体

*/

- (void)sendMessage:(NSString *)message {

    if (message) {       

        NSError *error;

        [self.webSocket sendString: message error:&error];

        if (error) {

            NSLog(@"发送消息失败!");

        }else

        {

            NSLog(@"消息已发送");

        }

    }

}

/**

发送ping消息

*/

- (void)sendPingMessage {

    NSError *error;

    [self.webSocket sendPing:[NSData data] error:&error];

    if (error) {

        NSLog(@"发送心跳包失败!");

    }else

    {

        NSLog(@"发送心跳包");

    }

}

#pragma mark - SRWebSocketDelegate

/**

Called when a frame was received from a web socket.

@param webSocket An instance of `SRWebSocket` that received a message.

@param string    Received text in a form of UTF-8 `String`.

*/

- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)string {

    NSLog(@"收到信息:%@",string);

}

/**

Called when a given web socket was open and authenticated.

@param webSocket An instance of `SRWebSocket` that was open.

*/

- (void)webSocketDidOpen:(SRWebSocket *)webSocket {

    NSLog(@"已链接服务器:%@",webSocket.url);


    //重置计数器

    self.currentCount = 0;

    self.status = HXSocketStatusConnected;

}

/**

Called when a given web socket encountered an error.

@param webSocket An instance of `SRWebSocket` that failed with an error.

@param error    An instance of `NSError`.

*/

- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {


    NSLog(@"链接失败:%@",error.localizedDescription);


    self.status = HXSocketStatusFailed;


    //尝试重新连接

    [self reconnect];

}

/**

Called when a given web socket was closed.

@param webSocket An instance of `SRWebSocket` that was closed.

@param code      Code reported by the server.

@param reason    Reason in a form of a String that was reported by the server or `nil`.

@param wasClean  Boolean value indicating whether a socket was closed in a clean state.

*/

- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(nullable NSString *)reason wasClean:(BOOL)wasClean {

    NSLog(@"链接已关闭:code:%zd  reason:%@",code,reason);

    if (code == SRStatusCodeNormal) {

        self.status = HXSocketStatusClosedByUser;

    }else

    {

        self.status = HXSocketStatusClosedByServer;

        //尝试重新连接

        [self reconnect];

    }

}

/**

Called on receive of a ping message from the server.

@param webSocket An instance of `SRWebSocket` that received a ping frame.

@param data      Payload that was received or `nil` if there was no payload.

*/

- (void)webSocket:(SRWebSocket *)webSocket didReceivePingWithData:(nullable NSData *)data {

    NSLog(@"收到 Ping");

}

/**

Called when a pong data was received in response to ping.

@param webSocket An instance of `SRWebSocket` that received a pong frame.

@param pongData  Payload that was received or `nil` if there was no payload.

*/

- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(nullable NSData *)pongData {

    NSLog(@"收到 Pong");

}

@end

完全自动化,你只需要关心发送消息、接收消息即可。

---------------------

作者:TheLittleBoy

来源:CSDN

原文:https://blog.csdn.net/thelittleboy/article/details/83993489

版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(SocketRocket --- iOS使用篇)