IOS之WebSocket框架Starscream案例详解

传统的网络技术 (也就是 Berkeley sockets) 被认为是可靠和稳定的。但是 Berkeley socket 在某些 web 技术,比如代理和防火墙下不太好使。WebSocket 出现于 2011 年,是一种在客户端和服务端之间建立双向通讯的新技术。WebSocket 比起多个 HTTP 请求来说更有效率并允许长连接。

在 iOS 上使用 WebSocket 并不是那么容易。iOS 和 Mac 库 Starscream 的出现,极大地简化了 WebSocket 的创建和使用。

注:本文假设你熟悉 CocoaPods。如果你不熟悉,请参考我们的 CocoaPods 教程

在本文中,你将在一个叫做 Emoji Commuicator 的 App 中完成网络编程部分。Emoji Communicator 允许你将当前心情用一个 emoji 字符发布给所有连接到该服务的人。

Emoji Communicator 原来的开发者原本打算用 HTTP 请求获取新消息,但这个功能使用 WebSocket 显然更合适。你将使用 Starscream 来连接后台的 Web 服务器。

开始

首先需要一个 Web 服务器。在本文中,你会在本机上启动一个 web 服务器。这个示例的 web 服务器运行在 Node.js 下,使用一小个 Javascript 文件来支持它。

当然,首先需要安装 Node.js。如果不确定是否已经安装,可以在终端窗口中输入命令:

node --version

如果报错,请按照下列步骤下载和安装 Node.js。否则,你会看到 Node.js 的版本号,你就可以跳过下一节 Node.js 的下载。

安装和下载 Node.js

https://nodejs.org/ 下载 Node.js 的最新安装包 (当前 2016.9.22 的最新版本是)。下载完安装包 (例如 node-v6.6.0.pkg),双击进行安装。参考提示进行,选择默认选项就行了。

安装完后,在终端中检查 Node.js 是否工作正常:

node --version

如果你没有看到 6.6.0 (或者你所安装的版本),或者报错,再次检查安装是否正确。

聊天服务器

你将用到一个聊天服务器。从这里下载示例 iOS app 和 Web 服务器代码。解压缩 zip 包到桌面或者某个文件夹。在终端中,切换到该目录,并进入 nodeapp 子目录。

这个程序需要一个第三方模块,需要用 Node.js 的包管理器 npm 来安装。在这个目录中,执行:

npm install websocket

输入下列命令启动聊天服务器:

node chat-server.js

你会看到类似如下输出:

Tue Sep 13 2016 18:54:44 GMT-0500 (CDT) Server is listening on port 1337

然后在浏览器 Safari 或 Chrome 中打开 frontend.html。 

输入一个昵称,发送一条测试消息。如果要在第二个客户端进行测试,重新打开一个浏览器或标签页,用同一个 Url。用另一个昵称登录,发送一条消息;你会看到消息立即出现在另一个浏览器里。

这充分说明了 WebSocket 的强大之处。每个浏览器都和 web 服务器有一个单独的长连接——没有刷新。当消息到达,服务器会自动向所有连接着的客户端进行广播。返回终端,你可以看到所有的聊天活动:

$ node chat-server.jsTue Sep 13 2016 18:54:44 GMT-0500 (CDT) Server is listening on port 1337Tue Sep 13 2016 18:55:19 GMT-0500 (CDT) Connection from origin null.Tue Sep 13 2016 18:55:19 GMT-0500 (CDT) Connection accepted.Tue Sep 13 2016 18:55:34 GMT-0500 (CDT) User is known as: Aaron with green color.Tue Sep 13 2016 18:55:37 GMT-0500 (CDT) Received Message from Aaron: HelloTue Sep 13 2016 18:58:49 GMT-0500 (CDT) Connection from origin null.Tue Sep 13 2016 18:58:49 GMT-0500 (CDT) Connection accepted.Tue Sep 13 2016 18:58:51 GMT-0500 (CDT) User is known as: James with red color.Tue Sep 13 2016 18:58:55 GMT-0500 (CDT) Received Message from James: This is pretty slick!Tue Sep 13 2016 18:59:03 GMT-0500 (CDT) Received Message from James: :]Tue Sep 13 2016 18:59:27 GMT-0500 (CDT) Peer undefined disconnected.

WebSockets

HTTP 第一次出现是 1991 年,它设计为一种请求/响应式的通讯机制。Web 浏览器用这种机制工作良好,用户请求 web 页,服务器返回内容。但某些时候,需要有新数据时不经过用户请求就通知用户——也就是,服务器推。

HTTP 协议无法很好地解决推模型。在 websocket 出现前,web 服务通过一系列浏览器刷新机制来实现推模型,但效率无法让人满意。

webSocket 实现了服务端推机制。新的 web 浏览器全都支持 WebSocket,这使得它的使用超级简单。通过 WebSocket 能够打开持久连接,大部分网络都能轻松处理 WebSocket 连接。

WebSocket 通常应用在某些数据经常性或频繁改变的场景。例如 Facebook 中的 web 通知、Slack 中的实时聊天、交易系统中的变化的股票价格。

在 iOS 中使用 WebSocket 比较麻烦,你必须进行大量的设置,而且内置的 API 根本帮不上忙。这时 Starscream 出现了——这个小巧、易于使用的库让你所有的烦恼不翼而飞。

Emoji Communicator

打开 EmojiTransmitter.xcodeproj。在模拟器中运行程序,程序很简单,它需要用户输入一个昵称,然后显示一个界面,让用户选择一个 emoji 发送,并显示任何接收到的 emoji。

这个 App 还没有完成网络部分。你将使用 Starscream 来执行所有的 WebSocket 网络请求。

有许多方法可以将 Starscream 集成到你的项目。CocoaPods 和 Carthage 是两种最常见的包管理器。你两种都可以用,但本文将使用 CocoaPods。

首先,关闭打开的项目。开启终端窗口,将目录切换至项目文件夹。在这个项目中已经有一个配置了 Starscream pod 的 Podfile 文件了。你可以直接安装 pod:

pod repo update; pod install

当 CocoaPods 结束安装,在 Xcode 8 中打开 EmojiTransmitter.xcworkspace 文件。运行程序,检查 App 是否能够运行。
打开 ViewController.swift,在 import UIKit 后加入:

import Starscream

然后,在 ViewController 类的 username 属性后增加一个属性:

var socket = WebSocket(url: URL(string: "ws://localhost:1337/")!, protocols: ["chat"])

这是创建 WebSocket 连接的核心。注意 URL 的歌声,协议是 ws 而不是 Http/https。protocols 参数指定为 chat,这取决于服务端的实现,这个协议可以被使用,也可能被忽略。在本 demo 中,忽略它即可。
接着在 viewDidLoad 方法后加入:

deinit {
  socket.disconnect(forceTimeout: 0)
  socket.delegate = nil
}

当 View Controller 被销毁时,强制关闭 WebSocket 连接。

在 Starscream 中所有的工作都放在 delegate 中进行。Starscream 也支持闭包,如果你不愿意使用委托的话。

在 ViewController.swift,在 fileprivate 扩展后增加一个扩展:

// MARK: - WebSocketDelegate
extension ViewController : WebSocketDelegate {
  public func websocketDidConnect(_ socket: Starscream.WebSocket) {

  }

  public func websocketDidDisconnect(_ socket: Starscream.WebSocket, error: NSError?) {

  }

  public func websocketDidReceiveMessage(_ socket: Starscream.WebSocket, text: String) {

  }

  public func websocketDidReceiveData(_ socket: Starscream.WebSocket, data: Data) {

  }
}

这 4 个委托方法必须实现,否则代码无法通过编译。

然后,在 viewDidLoad 方法的 super.viewDidLoad() 后面添加:

socket.delegate = self
socket.connect()

运行程序,输入昵称,点击 Next。返回 Node.js 控制台你将看到有一个连接通知。

现在,你已经能够连接到 Node.js App 了,接下来是发送消息到服务器。

首先,将 sendMessage(_:) 方法修改为:

func sendMessage(_ message: String) {
  socket.write(string: message)
}

这会发送消息(本例中,就是 emoji)到 Node.js 服务器。

然后,在 websocketDidConnect(_:) 方法中加入:

socket.write(string: username)

这会在连接建立后发送你在第一个界面中输入的昵称。这个服务器会将第一个接收到的消息当做用户名称。
在 websocketDidDisconnect(_:error:) 中加入:

performSegue(withIdentifier: "websocketDisconnected", sender: self)

无论什么原因,只要 socket 被断开,这都会让用户返回到输入昵称界面。如果在你自己的 App 中,你应当在这里进行更健全的错误处理。

接着,在 websocketDidReceiveMessage(_:text:) 方法中:

// 1
guard let data = text.data(using: .utf16),
  let jsonData = try? JSONSerialization.jsonObject(with: data),
  let jsonDict = jsonData as? [String: Any],
  let messageType = jsonDict["type"] as? String else {
    return
}

// 2
if messageType == "message",
  let messageData = jsonDict["data"] as? [String: Any],
  let messageAuthor = messageData["author"] as? String,
  let messageText = messageData["text"] as? String {

  messageReceived(messageText, senderName: messageAuthor)
}

收到的文字消息是可读的字符串——如果是 JSON,尝试将其转为集合对象。代码解释如下:

  1. 首先将字符串转为 NSData,然后将 NSData 传给 JSONSerialization 对象以将其转为载体并返回一个有效的对象。最后还检查了几个重要的 key,并设置对应的值。如果对象无效,直接通过 guard 语句退出。
  2. 过滤消息的 messageType,然后将数据传递给 messageReceived(messageText:, senderName:) 方法。

下面是一个从 Node.js 收到的 JSON 格式的消息示例:

{
  "type": "message",
  "data": {
    "time": 1472513071731,
    "text": ":]",
    "author": "iPhone Simulator",
    "color": "orange"
  }
}

运行 app,每当你发送一条消息,emoji 将会用你选择的 emoji 和昵称刷新。返回 web 控制台,你的 emoji 消息也会显示。

这就是 Starscream 的使用!

结束

在这里下载最终完成的项目。

Emoji Communicator 是一个使用 WebSocket 的最简单的例子。如果你想在已经存在的服务中使用 Starscream,你可以参考更多资料:

如果你有任何问题或建议,请在下面留言。

到此这篇关于IOS之WebSocket框架Starscream案例详解的文章就介绍到这了,更多相关IOS之WebSocket框架Starscream内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-08-25

iOS WebSocket长链接的实现方法

WebSocket WebSocket 是 HTML5 一种新的协议.它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大不同是:WebSocket 是一种双向通信协议. 由于项目需要创建一个聊天室,需要通过长链接,和后台保持通讯,进行聊天,并且实时进行热点消息的推送. 目前Facebook的SocketRocket应该是目前最好的关于SocketRocket使用的框架了.而且简

iOS开发项目- 基于WebSocket的聊天通讯(1)

公司项目需要开发一个类似QQ.微信的即时IM聊天功能,做到实时监控消息,需要用的技术是websocket. 概述WebSocket: 1.1 为什么我们需要WebSocket这样的实时的通信协议? WebSocket是web通信方式的一种,像我们熟知的HTTP协议也是web通信方式的一种.但是我们知道HTTP协议是一种无状态的协议,其服务端本身不具备识别客户端的能力,必须借助外部的一些信息比如说session和cookie,才能与特定的客户端保持通信.也就是说我们所发送的每一个HTTP的请求都会

iOS开发项目- 基于WebSocket的聊天通讯(2)

公司项目需要开发一个类似QQ.微信的即时IM聊天功能,做到实时监控消息,需要用的技术是websocket,今天整理下语言聊天这块:其实语言聊天,包含两部分,录音和音乐播放,关于简单语言聊天功能如下图: 录音 在AVFoundation框架中有一个AVAudioRecorder类专门处理录音操作,它同样支持多种音频格式.与AVAudioPlayer类似,你完全可以将它看成是一个录音机控制类,下面是常用的属性和方法: 先来了解下AVAudioRecorder的常用属性: @property (rea

PHP框架实现WebSocket在线聊天通讯系统

ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展 tp5的项目根目录下执行composer命令安装think-swoole: composer require topthink/think-swoole 话不多说,直接上代码: 新建WebSocket.php控制器: (监听端口要确认服务器放行,宝塔环境还需要添加安全组规则) <?php namespace app\home\controller; use t

php+html5基于websocket实现聊天室的方法

本文实例讲述了php+html5基于websocket实现聊天室的方法.分享给大家供大家参考.具体如下: html5的websocket 实现了双向通信,折腾了几天弄了个聊天室,分享给大家 <?php error_reporting(E_ALL); ob_implicit_flush(); $sk=new Sock('127.0.0.1',8000); $sk->run(); class Sock{ public $sockets; public $users; public $master;

使用WebSocket实现即时通讯(一个群聊的聊天室)

随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据. 传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据:这种客户端是主动方,服务端是被动方的传统Web模式对于信息变化不频繁的Web应用来说造成的麻烦

ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解

本文实例讲述了ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例.分享给大家供大家参考,具体如下: ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展(相关文章:Linux下源码包安装使用Swoole扩展) 在tp5的项目根目录下执行composer命令安装think-swoole: composer require topthink/think-swoole 安装成功: 话不多说

基于django channel实现websocket的聊天室的方法示例

websocket 网易聊天室? ​ web微信? ​ 直播? 假如你工作以后,你的老板让你来开发一个内部的微信程序,你需要怎么办?我们先来分析一下里面的技术难点 消息的实时性? 实现群聊 现在有这样一个需求,老板给到你了,关乎你是否能转正?你要怎么做? 我们先说消息的实时性,按照我们目前的想法是我需要用http协议来做,那么http协议怎么来做那? 是不是要一直去访问我们的服务器,问服务器有没有人给我发消息,有没有人给我发消息?那么大家认为我多长时间去访问一次服务比较合适那? 1分钟1次?1分

基于iOS开发证书和配置文件的使用

提示:之前只是根据网上的流程完成了iOS项目的发布过程,对于证书和配置文件仍是一头雾水,这里参照别人的文章,简单了解一下,毕竟以后用的着. 这里有几个问题: •什么是iOS证书,它是如何与app应用关联的? •iOS开发证书和生产证书有何区别,如何使用的? •证书与配置文件(Provisioning Profiles)是什么关系,配置文件在Xcode中如何使用? •证书以及配置文件如何申请? •什么是Key Pair(公钥/私钥)?如何与证书关联的? •签名的作用是什么? 1. 准备工作: 如果

golang基于websocket实现的简易聊天室程序

本文实例讲述了golang基于websocket实现的简易聊天室.分享给大家供大家参考,具体如下: 先说点无关的,最近忙于工作没有更新博客,今天休息顺便把golang websocket研究了一下,挺好玩的,写了一个聊天室,分享给大家. websocket包 : code.google.com/p/go.net/websocket 文档 : http://go.pkgdoc.org/code.google.com/p/go.net/websocket 首先安装websocket包 复制代码 代码

iOS开发之微信聊天工具栏的封装

微信大家基本上都用过,今天要做的就是微信的聊天工具条.聊天工具条还是比较复杂的,其中包括发送表情,发送文字,发送图片,发送声音,拍照等等功能,下面给出发送录音,文字,表情的代码,其他的和这几样类似.还是那句话百字不如一图,先来几张效果图吧. 在封装聊天工具条的的时候表情键盘是之前封装好的,所以拿过来就可以用的啦.因为不管是工具条还是表情键盘都是用约束来控件大小的,所以横屏也是没问题的,在大屏手机上也是没问题的.下面将会一步步讲解如何封装下面的聊天工具条.主要是对工具条的封装,表情键盘在这就不做讲