iOS 基础学习iOS 开发 Swift&Objective-C

iOS - 基于WebSocket的聊天通讯(1)

2016-08-03  本文已影响1775人  小兵快跑

公司项目需要开发一个类似QQ、微信的即时IM聊天功能,做到实时监控消息,需要用的技术是websocket,

WebSocket 聊天.png

概述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则是像打电话,服务器端和客户端可以同时向对方发送数据,它们之间存着一条持续打开的数据通道。

关于WebSocket先简单就说这些了,相关详细资料请参考扩展阅读;接着实现iOS端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:@"您好 !"];

    }
}


扩展阅读

WebSocket
细说WebSocket
借助Nodejs探究WebSocket
Web 消息推送及 WebSocket 简介
WebSocket 是什么原理?为什么可以实现持久连接
ios 有关websocket的一些理解


随手点个喜欢吧~

关注我

QQ--iOS 交流群:107548668

上一篇下一篇

猜你喜欢

热点阅读