iOSアクセスwebsocket
9391 ワード
1,websocket
Websocketはhtml 5が提案したプロトコル仕様である.ブラウザとサーバの全二重通信を実現し、サーバ資源と帯域幅をよりよく節約することができ、websocketは通信の規範を約束し、握手のメカニズムを通じて、クライアント(ブラウザ)とサーバ(webserver)の間にtcpのような接続を確立することができ、c-s間の通信を便利にする.Websocketが登場する前に、webインタラクションは一般的にhttpプロトコルに基づく短い接続または長い接続である.WebSocketは、クライアントとサービス側とのリアルタイム通信を解決するための技術である.Websocketプロトコルは本質的にtcpベースのプロトコルであり、HTTP/HTTPSプロトコルを介して特殊なhttpリクエストを開始して握手した後、データを交換するためのTCP接続を作成し、その後、サービス側とクライアントはこのTCP接続を通じてリアルタイム通信を行い、httpと最大の違いは、websocketは双方向通信プロトコルであり、接続が確立された後、Websocketサーバとクライアントは、socketのようにnegativeが積極的に相手にデータを送信または受信します.
2,websocketの利点
以前はウェブサーバがプッシュ技術やインスタント通信を実現していたが、ポーリング(polling)を用いており、特徴的な時間間隔(例えば1秒)でブラウザから自動的に要求を出し、サーバのメッセージをアクティブに引き戻す必要があった.この場合、サービスに絶えず要求を送信する必要があったが、HTTP requestのヘッダは非常に長い.含まれているデータは小さな値にすぎない可能性があります.これにより、帯域幅とサーバリソースが大幅に消費されます.
WebSocket APIの最も偉大な点は、サーバとクライアントが所定の時間範囲内の任意の時点で、互いに情報をプッシュできることである.ブラウザとサーバは握手の動作をするだけで、接続が確立された後、サーバは自発的にクライアントにデータを転送することができ、クライアントはいつでもサーバにデータを送信することができます.また,サーバとクライアントとの間で交換されるヘッダ情報は小さい.
3,websocketの使い方
『1』podインポートを使用しています
ライブラリをプロジェクトにインポートした後、まず1つをカプセル化します.
HHWebSocketManager
単一の例
《4》このフレームワークの最後の1つを使うのはとても重要で、注意しなければなりません
このフレームワークでカプセル化されたwebscoketは、sendPing senddataメソッドを呼び出す前に、現在のscoketが接続されているかどうかを判断しなければなりません.接続状態でなければ、プログラムはcrashになります.
《5》通知の追加
Websocketはhtml 5が提案したプロトコル仕様である.ブラウザとサーバの全二重通信を実現し、サーバ資源と帯域幅をよりよく節約することができ、websocketは通信の規範を約束し、握手のメカニズムを通じて、クライアント(ブラウザ)とサーバ(webserver)の間にtcpのような接続を確立することができ、c-s間の通信を便利にする.Websocketが登場する前に、webインタラクションは一般的にhttpプロトコルに基づく短い接続または長い接続である.WebSocketは、クライアントとサービス側とのリアルタイム通信を解決するための技術である.Websocketプロトコルは本質的にtcpベースのプロトコルであり、HTTP/HTTPSプロトコルを介して特殊なhttpリクエストを開始して握手した後、データを交換するためのTCP接続を作成し、その後、サービス側とクライアントはこのTCP接続を通じてリアルタイム通信を行い、httpと最大の違いは、websocketは双方向通信プロトコルであり、接続が確立された後、Websocketサーバとクライアントは、socketのようにnegativeが積極的に相手にデータを送信または受信します.
2,websocketの利点
以前はウェブサーバがプッシュ技術やインスタント通信を実現していたが、ポーリング(polling)を用いており、特徴的な時間間隔(例えば1秒)でブラウザから自動的に要求を出し、サーバのメッセージをアクティブに引き戻す必要があった.この場合、サービスに絶えず要求を送信する必要があったが、HTTP requestのヘッダは非常に長い.含まれているデータは小さな値にすぎない可能性があります.これにより、帯域幅とサーバリソースが大幅に消費されます.
WebSocket APIの最も偉大な点は、サーバとクライアントが所定の時間範囲内の任意の時点で、互いに情報をプッシュできることである.ブラウザとサーバは握手の動作をするだけで、接続が確立された後、サーバは自発的にクライアントにデータを転送することができ、クライアントはいつでもサーバにデータを送信することができます.また,サーバとクライアントとの間で交換されるヘッダ情報は小さい.
3,websocketの使い方
『1』podインポートを使用しています
pod 'SocketRocket'
《2》 ライブラリをプロジェクトにインポートした後、まず1つをカプセル化します.
HHWebSocketManager
単一の例
//.h
#import
#import
extern NSString * const kNeedPayOrderNote;
extern NSString * const kWebSocketDidOpenNote;
extern NSString * const kWebSocketDidCloseNote;
extern NSString * const kWebSocketdidReceiveMessageNote;
@interface HHWebSocketManager : NSObject
//
@property (nonatomic,assign,readonly) SRReadyState socketReadyState;
+ (HHWebSocketManager *)instance;
- (void)SRWebSocketOpen;//
- (void)SRWebSocketClose;//
- (void)sendData:(id)data;//
@end
//.m
#import "HHWebSocketManager.h"
NSString * const kNeedPayOrderNote = @"kNeedPayOrderNote";
NSString * const kWebSocketDidOpenNote = @"kWebSocketdidReceiveMessageNote";
NSString * const kWebSocketDidCloseNote = @"kWebSocketDidCloseNote";
NSString * const kWebSocketdidReceiveMessageNote = @"kWebSocketdidReceiveMessageNote";
@interface HHWebSocketManager()
{
int _index;
NSTimer * heartBeat;
NSTimeInterval reConnectTime;
}
@property (nonatomic,strong) SRWebSocket *socket;
@end
@implementation HHWebSocketManager
+(HHWebSocketManager *)instance{
static HHWebSocketManager *Instance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
Instance = [[HHWebSocketManager alloc] init];
});
return Instance;
}
#pragma mark - **************** public methods
-(void)SRWebSocketOpen{
// url return
if (self.socket) {
return;
}
self.socket = [[SRWebSocket alloc] initWithURLRequest:
[NSURLRequest requestWithURL:[NSURL URLWithString:@"youurl"]]];//
NSLog(@" websocket :%@",self.socket.url.absoluteString);
self.socket.delegate = self;
//
[self.socket open];
}
-(void)SRWebSocketClose{
if (self.socket){
[self.socket close];
self.socket = nil;
//
[self destoryHeartBeat];
}
}
#define WeakSelf(ws) __weak __typeof(&*self)weakSelf = self
- (void)sendData:(id)data {
NSLog(@"socketSendData --------------- %@",data);
WeakSelf(ws);
dispatch_queue_t queue = dispatch_queue_create("zy", NULL);
dispatch_async(queue, ^{
if (weakSelf.socket != nil) {
// SR_OPEN send ,
if (weakSelf.socket.readyState == SR_OPEN) {
//
[weakSelf.socket send:data];
} else if (weakSelf.socket.readyState == SR_CONNECTING) {
NSLog(@" , ");
// 2 socket.readyState , 10
// SR_OPEN [ws.socket send:data]
// 10 , , ,
// ,
[self reConnect];
} else if (weakSelf.socket.readyState == SR_CLOSING || weakSelf.socket.readyState == SR_CLOSED) {
// websocket , reConnect
NSLog(@" ");
[self reConnect];
}
} else {
NSLog(@" , , socket nil ");
NSLog(@" , ,socket==nil ");
}
});
}
#pragma mark - **************** private mothodes
//
- (void)reConnect
{
[self SRWebSocketClose];
// 5 2^5 = 64
if (reConnectTime > 64) {
// ,
return;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(reConnectTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.socket = nil;
[self SRWebSocketOpen];
NSLog(@" ");
});
// 2
if (reConnectTime == 0) {
reConnectTime = 2;
}else{
reConnectTime *= 2;
}
}
//
- (void)destoryHeartBeat
{
dispatch_main_async_safe(^{
if (heartBeat) {
if ([heartBeat respondsToSelector:@selector(isValid)]){
if ([heartBeat isValid]){
[heartBeat invalidate];
heartBeat = nil;
}
}
}
})
}
//
- (void)initHeartBeat
{
dispatch_main_async_safe(^{
[self destoryHeartBeat];
// 3 ,NAT 5
heartBeat = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(sentheart) userInfo:nil repeats:YES];
// ,
[[NSRunLoop currentRunLoop] addTimer:heartBeat forMode:NSRunLoopCommonModes];
})
}
-(void)sentheart{
// ping data
[self sendData:@"heart"];
}
//pingPong
- (void)ping{
if (self.socket.readyState == SR_OPEN) {
[self.socket sendPing:nil];
}
}
#pragma mark - socket delegate
- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
//
reConnectTime = 0;
//
[self initHeartBeat];
if (webSocket == self.socket) {
NSLog(@"************************** socket ************************** ");
[[NSNotificationCenter defaultCenter] postNotificationName:kWebSocketDidOpenNote object:nil];
}
}
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
if (webSocket == self.socket) {
NSLog(@"************************** socket ************************** ");
_socket = nil;
//
[self reConnect];
}
}
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean {
if (webSocket == self.socket) {
NSLog(@"************************** socket ************************** ");
NSLog(@" ,code:%ld,reason:%@,wasClean:%d",(long)code,reason,wasClean);
[self SRWebSocketClose];
[[NSNotificationCenter defaultCenter] postNotificationName:kWebSocketDidCloseNote object:nil];
}
}
/* pong , pong ,
, ,
, , ping ,
, ping ,
*/
-(void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload{
NSString *reply = [[NSString alloc] initWithData:pongPayload encoding:NSUTF8StringEncoding];
NSLog(@"reply===%@",reply);
}
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
if (webSocket == self.socket) {
NSLog(@"************************** socket ************************** ");
NSLog(@" message json , , ");
NSLog(@"message:%@",message);
[[NSNotificationCenter defaultCenter] postNotificationName:kWebSocketdidReceiveMessageNote object:message];
}
}
#pragma mark - **************** setter getter
- (SRReadyState)socketReadyState{
return self.socket.readyState;
}
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
『3』の使い方// socket
[[SocketRocketUtility instance] SRWebSocketOpen];
//
[[SocketRocketUtility instance] SRWebSocketClose];
《4》このフレームワークの最後の1つを使うのはとても重要で、注意しなければなりません
このフレームワークでカプセル化されたwebscoketは、sendPing senddataメソッドを呼び出す前に、現在のscoketが接続されているかどうかを判断しなければなりません.接続状態でなければ、プログラムはcrashになります.
《5》通知の追加
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(SRWebSocketDidOpen) name:@"kWebSocketDidOpenNote" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(SRWebSocketDidReceiveMsg:) name:@"kWebSocketdidReceiveMessageNote" object:nil];
- (void)SRWebSocketDidOpen {
NSLog(@" ");
// 。。。
}
- (void)SRWebSocketDidReceiveMsg:(NSNotification *)note {
//
NSString * message = note.object;
NSLog(@"%@",message);
}