iOS基于WebSocket的聊天机制

作者: 1seven | 来源:发表于2015-12-22 10:31 被阅读12748次

    WebSocket 的使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道。Web 开发人员可以非常方便地使用 WebSocket 构建实时 web 应用。

    1.WebSocket 机制

    以下简要介绍一下 WebSocket 的原理及运行机制。

    WebSocket 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大不同是:

    WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 Browser/Client Agent 都能主动的向对方发送或接收数据,就像 Socket 一样;

    WebSocket 需要类似 TCP 的客户端和服务器端通过握手连接,连接成功后才能相互通信。

    使用 WebSocket 模式客户端与服务器的交互如下图:

    WebSocket 是类似 Socket 的 TCP 长连接的通讯模式,一旦 WebSocket 连接建立后,后续数据都以帧序列的形式传输。在客户端断开 WebSocket 连接或 Server 端断掉连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。

    2.在iOS中WebSocket的具体实现

    1>下载WebSocket的sdk,并导入工程里面

    2>在聊天的控制器里导入头文件代理等

    3>具体使用

    //连接端口

    _webSocket.delegate = nil;

    [_webSocket close];

    _webSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"ws://www.qsjia.com:7272"]]];

    _webSocket.delegate = self;

    [_webSocket open];

    NSLog(@"open success!");

    [self webSocketDidOpen:_webSocket];

    //实现代理方法

    #pragma SRWebSocketDelegate

    //连接成功

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

    {

    NSLog(@"Websocket Connected");

    }

    //连接失败

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

    {

    NSLog(@":( Websocket Failed With Error %@", error);

    _webSocket = nil;

    }

    //接收到新消息的处理

    - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;

    {

    NSLog(@"Received \"%@\"", message);

    self.str = message;

    self.myMessage = [ChatViewController dictionaryWithJsonString:self.str];

    self.ping = [self.myMessage objectForKey:@"type"];

    if ([self.ping isEqualToString:@"say"]) {

    [self addMessage];

    [self.arr enumerateObjectsUsingBlock:^(PersonDetail*  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

    if ( [obj.myid integerValue] == [self.myMessage[@"roomid"] integerValue]) {

    [self.arr exchangeObjectAtIndex:idx withObjectAtIndex:0];

    }

    }];

    [self.tableView reloadData];

    }

    //[self.tableView reloadData];

    }

    //连接关闭

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

    {

    NSLog(@"WebSocket closed");

    //self.title = @"Connection Closed! (see logs)";

    _webSocket = nil;

    }

    //登录服务器要发送的字符串(根据具体后台设置)

    //获取UserDefault

    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];

    NSString *uid = [userDefault objectForKey:@"uid"];

    NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"login",@"type",@"1",@"room_id",uid,@"client_name", nil];

    [dic enumerateKeysAndObjectsUsingBlock:^(NSString * key, id obj, BOOL *stop) {

    if ([key isEqualToString:@"client_name"]) {

    [dic setValue:@([uid intValue]) forKey:@"client_name"];

    }else if ([key isEqualToString:@"room_id"]){

    [dic setValue:@([@"1" intValue]) forKey:@"room_id"];

    }

    }];

    NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:NULL];

    NSString *string = [[ NSString alloc ] initWithData :data encoding : NSUTF8StringEncoding];

    //NSLog(@"%@",string);

    [_webSocket send:string];

    //退出服务器要发送的字符串

    NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"loginout",@"type",nil];

    NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:NULL];

    NSString *string = [[ NSString alloc ] initWithData :data encoding : NSUTF8StringEncoding];

    [_webSocket send:string];

    webSocket一般是配合数据库一起使用的,实现的逻辑要根据具体情况来确定的.

    相关文章

      网友评论

      • Albert新荣:写的不错
      • ShenYj:程序进入后台后, 有啥注意的?
      • LD_左岸:求 楼主的 demo
      • 我的大名叫小爱:请问一下有没有websocke连接错误码返回的使用方法呀? 我知道有个方法 但是错误码 哪里找啊.
      • 帆123:楼主,[_webSocket open] 直接跳转到 close回调方法了,请问楼主知道这个是什么原因吗?
      • 42e1c79aee08:楼主,你导入的 socketRocket的时候,工程没有报错吗?
      • 猪猪的思维有点长:WebRTCDemo[293:17325] -[AppDelegate webSocket:didFailWithError:]
        2016-09-30 09:28:02.113811 WebRTCDemo[293:17325] Error Domain=SRWebSocketErrorDomain Code=2132 "received bad response code from server 400" UserInfo={NSLocalizedDescription=received bad response code from server 400, HTTPResponseStatusCode=400}

        请问楼主知不知道这个问题是什么,搜了半天没搜到
      • d8118b547088:楼主,我的问题和12楼的一样,能解决吗
      • e5fb1e513efd:楼主 你做 iOS webSocket 聊天了吗 能加个 qq 吗 最近也在做
        ali_hilo:@爱吃土豆的程序媛 你好 加个QQ吗 (734079970) 正在iOS 对接webSocket 可以交流指导一下吗 ? 谢谢
      • xvvvvvvvvvv:楼主:你好 为什么我连接成功之后发送消息就跳到socket 关闭方法里面。。Websocket Connected ->sendMessage->WebSocket closed
      • VoiderSun:ld: framework not found SocketRocket
      • embraceChange:你好,我想问下 [_webSocket send:string] 现在改成 sendString 或者 sendData 了,那么向后台发送这段代码应该写在哪里呢?我现在发送报错 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid State: Cannot call send: until connection is open' 暂未找到答案,求楼主帮解答
        RYC:@embraceChange 方便加个QQ吗,我也准备做这块,请教下,谢谢
        embraceChange:@RYC 是的
        RYC:@embraceChange 你们做聊天了?
      • 跑调的安眠曲:发送大文件,home挂起之后怎么解决?
      • 槑头脑:楼主 在登陆的时候 为什么要把键值转化为NSNumber类型的呢
        1seven:@Royal丶MJZ 这要根据你们后台的设置,我们后台设置是登陆直接拼登录的字符串,后台接收到的就是我要登录的信息,得和后台一致,我写的只是个例子
      • b1084fe009c4:问下,程序运行中websocker 断开了 在哪里重新连接。
      • 1f0f77826518:如何在退出的时候关闭 websocket
      • ValienZh:socket.io 可以替换websocket 么
        my我的:@菜鸟中的战斗鸡 哥们socketio的那个实现了吗
        my我的:哥们你的socketio的实现了吗
        菜鸟中的战斗鸡:求一个socket.io的demo
      • 1seven:https://github.com/square/SocketRocket我用的这个,导入了几个类
        IT杰哥:怎么解决?
        8381e5f2472b:@1seven Websocket Failed With Error Error Domain=NSURLErrorDomain Code=-1001 "Timed out connecting to server. 有没有遇到过这问题???怎么解决
        VoiderSun:@1seven 导入了哪几个类啊,为什么我这一直报错找不到SocketRocket.framework,我明明导入进去,还重新弄好了几次,还是找不到,什么情况呢?
      • 1f0f77826518:我用的是 xcode 7 倒入后 socketRocket.h 里面代理方法报错请问怎么解决?求解啊
        Cassiel_Apricot:@riseup 问题解决了没?
      • 1f0f77826518:在哪下载?
        1f0f77826518:@1seven 我用的是 xcode 7 倒入后 socketRocket.h 里面代理方法报错请问怎么解决?求解啊
        1seven:@riseup github上

      本文标题:iOS基于WebSocket的聊天机制

      本文链接:https://www.haomeiwen.com/subject/manmhttx.html