一步一步教你用WebSocket进行消息推送(iOS版本)

  写作原因:公司这个月的项目计划是优化推送;目前我们推送用的个推(不是不好,项目限制),然后服务器那边人员忙(本人菜鸡iOS程序员),所以我就自己来做咯,如果有错误的地方下面留言我们一起交流哈,要源码的记得回复留下地址哦

  大家都知道用APNS(个推那些都是基于这个的)只能推送一些不重要的消息(比如公告,推荐你买啥啥啥),但是我们项目有加圈子/发任务/会议等等非常重要的操作,这种是不能用APNS来做的,那么我们应该用什么呢?我们应该用聊天那种来推送;当然说起聊天我们技术就多了,你可以使用最裸奔的socket(https://github.com/robbiehanson/CocoaAsyncSocket)自己做协议,也可以使用封装了一下的websocket(https://github.com/facebook/SocketRocket)等等,甚至封装更深的socket.io(https://github.com/pkyeck/socket.IO-objc)等等;当然你也知道答案了,websocket最适合来做推送。我们先来看看最终效果吧,如果你觉得感兴趣,可以继续往下看:

我们在我们的服务器上输入一个内容,点击按钮
模拟器上就会收到消息

  那么现在开始说下准备工作,1:你要会点H5,2:你要知道websocket是啥东西,3:你要有一个heroku账号(有免费的nodejs环境服务器),4:你要会点终端(包括解决神秘代码和常用命令);好的现在解释下为什么要用nodejs来做服务器,因为他天生就适合websocket;那么为什么要用heroku呢,因为我之前用新浪云,新浪云也有nodejs环境,但是要收费(土豪忽略),于是找了一个大家都拍手称快的heroku;那么我们开始做咯。

第一步:本地先弄个简单的websocket服务器

我们使用npm管理器来创建,首先自己在尽量没有中文路径的地方创建一个文件夹(名字就叫做hellowebsocket),然后我们用终端进入文件夹:

进入文件夹

创建一个基础项目:

创建基础项目

创建一个server.js(websocket服务器文件):

创建服务器文件

配置package.json文件,覆盖或者修改成这样:

修改配置文件

其中的scripts我们定义一个start为node server.js操作,也就是说你输入npm start相当于是执行node server.js,

我们来安装一些工具,express(用来搭建http协议的网页,我们不是要做一个网页吗?这个网页是http协议的,我们肯定要搭建咯),ws(websocket的node封装),在命令行依次输入以下命令:1:npm install --save --save-exact express,2:npm install --save --save-exact ws bufferutil utf-8-validate,

我们来创建一个网页,取名index.html,内容先简单点,点击按钮显示输入框的内容,还没有连接websocket服务器(server.js,以后不再注释):

弹出文本框内容

现在我们来编辑weboscket服务器咯,先简单点,搭建一个http协议让index.html可以本地浏览器输入localhost:3000/index.html访问,还没有创建websocket监听,等一下来:

搭建http环境

然后在终端中输入npm start,这时候你在浏览器中输入localhost:3000/index.html,就可以看到下面的效果了:

HTTP搭建好了

接下面我们修改一下index.html和server.js,让index.html连接websocket服务器,weboscket服务器收到连接后发送回调消息"device your connect!",然后index.html收到回调消息后弹窗,内容如下:

server.js内容
index.html内容

这时候我们终端输入npm start,浏览器中输入localhost:3000/index.html就会弹出来回调消息了:

页面弹出连接成功的回调消息

通过以上的几步,大家应该大致知道推送原理了把,就是通过websocket连接得到的标示符进行发送消息和接收消息

第二步:网页输入内容点击按钮,websocket服务器响应并回调相同的内容,网页收到后弹窗

 通过第一步,大家可以暂定自己想一下这个怎么做,是这样的:我们index.html连接成功后我们通过标识符发送消息到websocket服务器,websocket服务器收到后得到内容并发送到index.html就可以了;那么同样的,我们修改一下内容:

server.js内容
index.html内容

同样的,执行npm start,浏览器中输入localhost:3000/index.html,然后输入框输入内容点击按钮就可以看到效果了:

效果图

现在我们越来越得心应手了,发现这么简单啊(好吧,下一篇我们才要开始做我们真正的目的呢,高兴啥)

第三步:我们用iOS连接websocket服务器把发送的和收到的消息展示到表格视图

经过以上的两步,我们终于揭开了神秘的websocket服务器面纱,我们决定要是一步一步实现iOS应用的推送,废话不对说,我们新建一个iOS工程并导入SRWebSocket库(这里没有教程,自己弄),然后写一个表格视图和数组,我们把发送消息和接收消息存到数组中用表格视图展示出来,重点代码如下:

连接websocket服务器

发送消息

接收消息

发送心跳,频率可设

还是不要忘记了,我们执行npm start,然后我们用模拟器打开点击右上角的“+”号发送消息就能看到以下的效果了:

效果图

好的,离目标又近了,现在我们来点有意思的

第四步:iOS端和index.html都连接到websocket服务器,index.html点击按钮发送输入内容到websocket服务器,web socket服务器发送消息到iOS端,iOS端收到消息并显示到表格视图

大家应该猜到怎么做了,主要难点是遍历所有的websocket连接,依次发送消息,我们暂时去掉index.html收到消息弹窗的代码,iOS端代码不用修改,主要内容如下:

index.html

server.js

然后依然,执行nam start,iOS启动模拟器,然后浏览器中输入localhost:3000/index.html,输入内容点击按钮,我们就可以看到下面的效果:

发送消息

模拟器收到消息

大家发现是不是和我们的最终效果有点像呢?其实还差得远呢,我们下一篇开始好好写一下细节部分

第五步:我们让每个连接的websocket有一个对应的标识符,以便单独的向某一个人发送消息

细心的小伙伴发现了,我们用index.html连接websocket服务器时后面带了一个userId参数,好吧暴露了其实我们连接的时候url后面是可以加参数的,我们暂且就先用这个来和websocket连接做一个映射吧,我们这一步不使用index.html,我们用iOS端连接并带上参数userId,然后在终端打印出来userId参数的值;有人问了,userId我在iOS请求时加上,那么在websocket服务器那边怎么收到呢?这个问题问的很好,我们来做一下实验,首先我们先改造一下iOS连接的代码,如下:

iOS连接websocket带上参数

然后我们在websocket服务器收到连接后把socket连接打印出来,代码如下:

websocket打印连接实例

依然,npm start,iOS端启动,这时候终端会输出一大片东西(这就是实例咯),然后你会在中间位置看到这样的东西:

参数位置

没错,我们就是要取出来这个东西,然后和websocket绑定,我们先在weboscket服务器文件上建立一个字典,然后连接的地方取出userId然后dic[userId]=websocket就可以了,为了看到效果,我们就把userId打印到终端显示吧,代码如下:

server.js内容

老话题,npm start,然后启动iOS端,就会终端打印出来了:

效果图

转入正题,我们既然都知道谁的连接是哪个了,那么我们接下来要做的就是在websocket服务器中接收消息(我们用index.html发消息,充当"业务服务器");然后websocket服务器判断消息是要发给谁的,然后在字典中找到那个socket连接,调用send函数即可(当然还有其他很多的方法,可能我这个不标准),我们修改server.js为以下代码:

给指定的userid发消息

然后我们修改一下index.html文件,给指定的userId为10001的人发送消息,消息格式在websocket服务器中定义好了,所有我们index.html给websocet发消息时要遵从消息格式加上分隔符"^"等,代码如下:

让web socket服务器给userId=10001的人发消息

我们让iOS端的userId设置成10001,然后npm start,浏览器中输入localhost:3000/index.html,启动模拟器,浏览器中输入内容点击按钮,这时候会看到如下效果:

发送消息

iOSuserId=10001的用户收到消息

当然了,你可以多建几个工程,设置连接不同的userId,然后 index.html也可以设置不限userId和限制多个userId发消息,你可以多测试一下效果。那么接下来的系列我们将把本地服务器部署到heroku上成为全局的,然后各地的个小伙伴都可以访问到了,你可以先自己折腾下,我先给个网址给你们https://devcenter.heroku.com/articles/node-websockets

第六步:把websocket服务器部署到heroku服务器变为全局访问

有的人有个好东西就想分(xuan)享(yao)(就是我),其实websocket服务器成为全局访问后,你发你女朋友这个网址(前面的index.html文件),让她在里面里输东西,点一下按钮;你就能施展"神通"知道她写的是什么,是不是很完(zhuang)美(bi)呢?那么现在就开始吧。上一步我最后留了一个网址,里面的内容是不是还是看不懂啊(反正我最开始没看懂,不然不会折腾这么几天),那么用我的方式来讲讲吧。

首先,你要有个heroku的账号,然后安装heroku-toolbelt.pkg工具(我们假设完全终端里操作,不在heroku官网操作),地址在这里https://devcenter.heroku.com/articles/heroku-command-line,然后安装,然后终端进入我们的目录中(一直都是hellowebsocket文件夹哦),执行heroku login(输入密码时是没有回显的),然后初始化一个git工程,执行git init,创建一个heroku项目,执行heroku create hellowebsocket(后面的名字自己看着办,如果有错误回提示你的,重新想一个就是了)然后你会看到两个地址(前面的就是你的全局地址咯,现在还访问不了,慢慢来,后面的是你的git地址),这时候我们执行git remote add hellowebsocket https://git.heroku.com/hellowebsocket.git(第5个参数是你的git地址,用你自己的),

其次,还有重要的东西,还记得我们之前安装了一些工具类吗?就是node_modules文件夹里面的东西,这些东西不用提交到git项目上去,所以我们建立一个.gitignore文件忽略掉,里面就写上node_modules就可以了;还有,我们本地服务器可以npm start执行nodejs环境,那heroku怎么去执行呢?我们应该建立一个Procfile文件,里面写上web: node server.js,这样目录里面就有这些内容了:

hellowebsocket目录

好了,现在可以提交了,git add .,git commit -m 'init',git push hellowebsocket master,然后等待部署吧,你会看到如下的信息表示成功部署:

部署成功

部署成功后heroku那边会自动启动nodejs环境服务器(相当于我们本地的npm start),然后我们在浏览器中输入上图黑色箭头的地址就会看到如下结果:

地址可全局访问了

第七步:实现最终效果,目标达成

把我们的iOS端的websocket连接地址换掉,代码如下:

iOS连接全局 websocket服务器

然后我们启动iOS端,浏览器中输入地址hellowebsocket.herokuapp.com/index.html,文本框中输入内容,iOS端就会显示了,效果如下:

输入推送内容

iOS收到推送消息

好了,这里面还有一个小问题留给你们,我们那个html文件没有发送心跳哦,你们去加上,还有就是可以设置心跳的频率,你们也可以研究研究;当然了,推送不仅仅是这样,我们的业务服务器(目前来说我们的index.html有点像)要考虑用户不在线的情况要把消息存起来同时发个APNS提醒用户,然后等用户上线后再取出消息发送出去,这部分的话我没有实现,交给你们啦;还有就是业务服务器和websocket服务器分工要明确,目前我的可能都是错误的(因为我的判断逻辑在websocket服务器,websocket服务器应该只负责发送,逻辑应该写在业务服务器),慢慢学习吧!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一种新的协议。它实...
    香橙柚子阅读 22,958评论 8 183
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,613评论 4 59
  • Dear:刚醒来,睁眼之初意识到今天是2017年的第一天,我心里泛起喜悦,“dear,happy new year...
    田心远阅读 170评论 9 3
  • 今天罗胖在得到的直播里,请到了一个人。此前他也提到过,说他练三个月书法就出字帖了,分别练三个月吉他、钢琴,就出教程...
    薛定饿着猫阅读 171评论 0 0
  • 在一切宣布结束,在事情真的无能为力之时,到底要怎样,才会让自己的心有一丝丝宽慰? 我不想说什么,真的有一种哽咽。或...
    公皙瓊羽阅读 128评论 0 0