在直播中,聊天和发礼物,需要用到及时通讯技术,市面上的App大多数采用的都是第三方SDK,融云,环信等,但是本例子采用websocket搭建及时通讯服务器。
即时通讯
即时通讯(Instant messaging,简称IM)是一个终端服务,允许两人或多人使用网路即时的传递文字讯息、档案、语音与视频交流
即时通讯技术原理(了解Socket)
-
Socket介绍: 套接字或者插座,用于描述IP地址和端口号,是一种网络的通信机制。
-
Socket作用: 网络通信底层都是通过socket建立连接的,因为它包含IP和端口,只要有这两个就能准确找到一台主机上的某个应用。
-
IM通信原理(T):
-
客户端A与客户端B如何产生通信?客户端A不能直接和客户端B,因为两者相距太远。
-
这时就需要通过IM服务器,让两者产生通信.
-
客户端A通过socket与IM服务器产生连接,客户端B也通过socket与IM服务器产生连接
-
A先把信息发送给IM应用服务器,并且指定发送给B,服务器根据A信息中描述的接收者将它转发给B,同样B到A也是这样。
-
通讯问题: 服务器是不能主动连接客户端的,只能客户端主动连接服务器
-
那么当服务器要推信息给客户端B,但是客户端B这时候没有与服务器产生连接,就推送不了.
-
这样就延迟,不即时了。
-
即时通讯技术实现
-
即时通讯核心是`即时``,那怎么达到即时?
-
目前实现即时通讯的有四种方式(短轮询、长轮询、SSE、Websocket)
-
短轮询: 每隔一小段时间就发送一个请求到服务器,服务器返回最新数据,然后客户端根据获得的数据来更新界面,这样就间接实现了即时通信。优点是简单,缺点是对服务器压力较大,浪费带宽流量(通常情况下数据都是没有发生改变的)。
-
短轮询: 主要是客户端人员写代码,服务器人员比较简单,适于小型应用
-
长轮询: 客户端发送一个请求到服务器,服务器查看客户端请求的数据(服务器中数据)是否发生了变化(是否有最新数据),如果发生变化则立即响应返回,否则保持这个连接并定期检查最新数据,直到发生了数据更新或连接超时。同时客户端连接一旦断开,则再次发出请求,这样在相同时间内大大减少了客户端请求服务器的次数.
-
长轮询底层实现:在服务器的程序中加入一个死循环,在循环中监测数据的变动。当发现新数据时,立即将其输出给浏览器并断开连接,浏览器在收到数据后,再次发起请求以进入下一个周期
-
长轮询弊端:服务器长时间连接会消耗资源,返回数据顺序无保证,难于管理维护
-
长轮询处理:不能一直持续下去,应该设定一个最长时限,可以通过心跳包的方式,设置多少秒没有接到心跳包,就关闭当前连接。
-
心跳包
:就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包 -
SSE(Server-sent Events服务器推送事件):为了解决浏览器只能够单向传输数据到服务端,HTML5提供了一种新的技术叫做服务器推送事件SSE,SSE技术提供的是从服务器单向推送数据给浏览器的功能,但是配合浏览器主动请求,实际上就实现了客户端和服务器的双向通信.
-
WebSocket:上面的这些解决方案中,都是利用浏览器单向请求服务器或者服务器单向推送数据到浏览器,而在HTML5中,为了加强web的功能,提供了websocket技术,它不仅是一种web通信方式,也是一种应用层协议。它提供了浏览器和服务器之间原生的全双工跨域通信,通过浏览器和服务器之间建立websocket连接,在同一时刻能够实现客户端到服务器和服务器到客户端的数据发送.
-
WebSocket
-
什么是websocket?是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据
-
WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 客户端 都能主动的向对方发送或接收数据,就像 Socket 一样。
-
WebSocket 需要类似 TCP 的客户端和服务器端通过握手连接,连接成功后才能相互通信
-
websocket提供两种数据传输:文本数据和二进制数据
-
websocket协议头:ws
WebSocket原理
-
Websocket流程: WB是先进行一次HTTP请求,这个请求头不同于普通HTTP请求,然后服务器开始辨认请求头,如果是WB的请求头,则开始进行普通的TCP连接,即三次握手。如果不是WB的HTTP请求头,那就是按普通的HTTP请求处理
-
Websocket协议解析:
-
请求头
响应头
-
-
Sec-WebSocket-Key:其值采用base64编码的随机16字节长的字符序列
-
Sec-WebSocket-Accept如何生成:http://www.cnblogs.com/hustskyking/p/websocket-with-node.html
-
Socket.IO简介
-
WebSocket的功能是很强大的,使用起来也灵活,可以适用于不同的场景。不过WebSocket技术也比较复杂,需要加密解密,包装协议,自己实现3次握手,还需要对数据流进行加密解密处理,服务器端和浏览器端的实现都不同于一般的Web应用,因此自己实现很麻烦,可以使用Socket.IO框架。
-
Socket.IO:是一个完全由JavaScript实现、基于Node.js、支持WebSocket的协议用于实时通信、跨平台的开源框架。
-
Socket.IO:它包括了客户端(iOS,Android)和服务器端(Node.js)的代码,可以很好的实现iOS即使通讯技术。
-
Socket.IO框架地址: https://github.com/socketio
Socket.IO教程
Socket.IO建立连接 服务器代码
-
1.如何导入Socket.IO?
-
和导入express框架一样,使用package
-
给package文件添加依赖
-
2.如何创建socket
-
socket本质还是http协议,所以需要绑定http服务器,才能启动socket服务.
-
而且需要通过web服务器监听端口,socket不能监听端口,有人访问端口才能建立连接,所以先创建web服务器
3.如何建立socket连接(服务器不需要主动建立连接,建立连接是客户端的事情,服务器只需要监听连接)
-
客户端主动连接会发送connection事件,只需要监听connection事件有没有发送,就知道客户端有没有主动连接服务器
-
Socket.IO本质是通过
发送和接受事件
触发服务器和客户端之间的通讯,任何能被编辑成JSON或二进制的对象都可以传递。 -
监听事件,用socket.on,这个方法会有两个参数,第一个参数是事件名称,第二个参数是监听事件的回调函数,监听到就会执行这个回调函数
-
监听connection,回调函数会传入一个连接好的socket,这个socket就是客户端的socket
-
socket连接原理,就是客户端和服务端通过socket连接,服务器有socket,客户端也有
-
-
书写客户端代码,验证是否能建立连接
-
Socket.IO建立连接 客户端代码
-
1.下载Socket.IO-Client-Swift
-
Socket.IO只有swift,如果需要用OC代码,需要swift和OC混编
-
还有如果代码是OC,并且使用cocoapods,就不要使用cocoapods导入swift代码,会有问题.
-
-
2.下载完了,直接把Source文件夹拖入到自己工程中.
-
会报错,说当前swift版本过时,需要更新。点击Xcode顶部Edit => Convert => TO Current Swift Syntas 就好了。
-
-
3.OC和Swift混编,Swift代码怎么在OC中使用,直接导入”工程文件名-Swift.h”就可以使用,这个文件Xcode会自动帮我们生成,无序手动自己生成.
-
4.注意工程文件名不能带有-这个符号,而且有时候会延迟,并不是马上导入”工程文件名-Swift.h”就好.
-
5.创建socket对象,然后连接用connect方法,socket对象需要强引用
-
注意协议:ws开头
-
创建socket对象,需要传入字典,字典配置如下。
-
-
6.因为需要进行3次握手,不可能马上建议连接,需要监听是否连接成功的回调,使用on方法
-
7.ON方法两个参数(第一个参数,监听的事件名称,第二个参数:监听事件回调函数,会自动调用)
-
回调函数也有两个参数(第一个参数:服务器传递的数据 第二个参数:确认请求数据)
-
在TCP/IP协议中,如果接收方成功的接收到数据,那么会回复一个ACK数据。
-
SocketIO发送事件,通过事件传递数据
SocketIO 客户端发送事件代码
-
注意:只有连接成功之后,才能发送事件
-
向服务器发送事件(emit:第一参数事件的名称,第二个参数传输的数据,是一个数组)
SocketIO 服务器监听事件代码
-
监听客户端事件,需要嵌套在连接好的connect回调函数中
-
必须使用回调函数的socket参数,如function(s)中的s,监听事件,因此这是客户端的socket,肯定监听客户端发来的事件
-
服务器监听连接的回调函数的参数可以添加多个,具体看客户端传递数据数组有几个,每个参数都是与客户段一一对应,第一个参数对应客户端数组第0个数据
SocketIO 服务器发送事件代码
-
这里的socket一定要用服务器端的socket
-
给当前客户端发送数据,其他客户端收不到.
-
发给所有客户端,不包含当前客户端
-
发给所有客户端,包含当前客户端
SocketIO 客户端监听事件代码
SocketIO分组
-
开发中什么场景需要使用SocketIO分组?(T)
-
一个客户端和服务器只会保持一个socket连接,比如直播App中会开很多主播房间,每个房间都有自己的聊天室,不可能每个聊天室都建立一个socket,但如果只有一个socket,比如A用户要给A主播间发送信息,怎么推送过去,通过服务器只能给当前客户端推送,那一推,当前客户端所有直播间都有A用户的信息。
-
怎么解决多个直播聊天室问题?
-
给每个主播的房间都分组,服务器就可以给指定组推送数据,就不会影响到其他直播间
-
SocketIO如何分组?
-
服务器代码: socket.join(),()里面放分组名称,与之对应的 socket.leave()
-
注意这里的socket是客户端的socket,也就是连接成功,传递过来的socket
-
-
socket分组的原理
,只要客户端socket调用join,服务器就会把客户端socket和分组的名称绑定起来,到时候就可以根据分组的名称找到对应客户端的socket,就能给指定的客户端推送信息. -
注意:一个客户端socket只能添加到一组,离开的时候,要记得移除.
-
客户端可以这样测试,搞两台电脑/两台手机在同一个局域网内,运行就有两个客户端,分别加入不同组.
-
服务器只给一个客户端socket发送信息,另外一个客户端收不到
-
服务器代码
关于:中科研拓
深圳市中科研拓科技有限公司专注提供软件外包、app开发、智能硬件开发、O2O电商平台、手机应用程序、大数据系统、物联网项目等开发外包服务,通过IT技术实现创造客户和社会的价值,成为优秀的软件公司,通过客户需求导向、开放式创新、卓越运营管理等战略的实施,全面打造公司的核心竞争力。很好软件外包公司、软件开发公司,联系电话400-0316-532,邮箱sales@zhongkerd.com,网址www.zhongkerd.com