公司項目需要開發一個類似QQ、微信的即時IM聊天功能,做到實時監控消息,需要用的技術是websocket。
概述WebSocket:
1.1 為什麼我們需要WebSocket這樣的實時的通信協議?
WebSocket是web通信方式的一種,像我們熟知的HTTP協議也是web通信方式的一種。但是我們知道HTTP協議是一種無狀態的協議,其服務端本身不具備識別客戶端的能力,必須借助外部的一些信息比如說session和cookie,才能與特定的客戶端保持通信。也就是說我們所發送的每一個HTTP的請求都會帶上請求頭中一些相應的信息還有cookie,這明顯會增加我們傳輸的信息的體量從而帶來一定的網絡延遲,對於一些對通信的實時性要求比較高的應用來說就是不可忍受的了,比如說聊天程序或者是運行在浏覽器中的實時小游戲。最郁悶的卻還是這些頭信息和cookie往往對於服務器響應客戶端的請求來說是多余的,也就是說雖然我每個請求都帶了這些信息,但是服務器與客戶端的交互過程中可能根本用不上這些信息。
為了改善HTTP請求的這種網絡延遲的情況,也出現了一些適應不同需求的其他的[web通信]方式,比如說:輪詢,長輪詢(long-polling),數據流,EventSouce等等,WebSocket便是其中一種。
實際上大多數基於因特網(或者局域網)的網絡鏈接通常都包含長連接和基於TCP套接字的雙向消息交換。但是TCP協議是屬於最底層的網絡通信協議了,讓一些不能信任的客戶端腳本去訪問底層的TCP套接字顯然是不太安全的,因此WebSocket實現了一種較為安全的方案,它允許客戶端腳本在客戶端和支持WebSocket協議的服務器之間創建雙向的套接字連接。從而使實時通信的某些網絡操作變得簡單。
1.2 WebSocket是如何工作的?
我們知道了WebSocket的主要作用是,允許服務器端與客戶端進行全雙工(full-duplex)的實時通信。這裡有個例子特別好:HTTP協議像發電子郵件,發出後必須等待對方回信;WebSocket則是像打電話,服務器端和客戶端可以同時向對方發送數據,它們之間存著一條持續打開的數據通道。
1.Pod導入SocketRocket
platform :ios,'7.0' target '白__Socket--Demo1' do pod 'SocketRocket', '~> 0.5.1' end
2.導入對象SRWebSocket
#import "ViewController.h" #import "SRWebSocket.h" @interface ViewController ()<SRWebSocketDelegate> @property(nonatomic,strong) SRWebSocket *webSocket; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } //初始化 - (void)Reconnect{ NSLog(@"1221---open"); self.webSocket.delegate = nil; [self.webSocket close]; self.webSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"ws://192.168.5.120:4141"]]]; self.webSocket.delegate = self; self.title = @"Opening Connection..."; [self.webSocket open]; } - (void)viewWillAppear:(BOOL)animated{ [self Reconnect]; } - (void)viewDidDisappear:(BOOL)animated{ // Close WebSocket self.webSocket.delegate = nil; [self.webSocket close]; self.webSocket = nil; }
3.SRWebSocketDelegate
//連接成功 //代理方法實現 #pragma mark - SRWebSocketDelegate - (void)webSocketDidOpen:(SRWebSocket *)webSocket{ NSLog(@"Websocket Connected"); self.title = @"Connected!"; } //連接失敗 - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error{ NSLog(@":( Websocket Failed With Error %@", error); self.title = @"Connection Failed! (see logs)"; self.webSocket = nil; } //接收到新消息的處理 - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message{ // NSString *str1 = self.replyContent.text; // NSString *str2 = [str1 stringByAppendingFormat:@"%@\n",message]; // self.replyContent.text = str2; NSLog(@"%@--askl",message); } //連接關閉 - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean{ NSLog(@"Closed Reason:%@",reason); self.title = @"Connection Closed! (see logs)"; self.webSocket = nil; } //該函數是接收服務器發送的pong消息,其中最後一個是接受pong消息的, 在這裡就要提一下心跳包,一般情況下建立長連接都會建立一個心跳包, 用於每隔一段時間通知一次服務端,客戶端還是在線,這個心跳包其實就是一個ping消息, 我的理解就是建立一個定時器,每隔十秒或者十五秒向服務端發送一個ping消息,這個消息可是是空的 - (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload{ NSString *reply = [[NSString alloc] initWithData:pongPayload encoding:NSUTF8StringEncoding]; NSLog(@"%@",reply); } #pragma mark - SendButton Response - (IBAction)sendAction:(id)sender { [self.view endEditing:YES]; // WebSocket if (self.webSocket) { [self.webSocket send:@"您好 !"]; } }
實現效果:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。