socket.io-直播视频的消息推送

近日接到需求,须要在“直播后台监控系统”里监控直播间的消息。刚接到需求时一脸懵逼,好在队友给力,Google强大,需求已经上线。现将我完成需求的过程与查阅了解到的知识整理出来,仅供参考,若错误请指教~~html

1、什么是WebSocket


WebSocket一种在单个TCP链接上进行全双工通信的协议。WebSocket通讯协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范,WebSocketAPI被W3C定为标准。前端

WebSocket 是独立的、建立在 TCP 上的协议,和 HTTP 的惟一关联是使用 HTTP 协议的101状态码进行协议切换,使用的 TCP 端口是80,能够用于绕过大多数防火墙的限制。java

WebSocket使得客户端和服务器之间的数据交换变得更加简单,容许服务端直接向客户端推送数据而不须要客户端进行请求,在 WebSocket API 中,浏览器和服务器只须要完成一次握手,二者之间就直接能够建立持久性的链接,并容许数据进行双向传送。node

1.背景


如今,不少网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,而后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器须要不断的向服务器发出请求,然而HTTP request的header是很是长的,里面包含的数据可能只是一个很小的值,这样会占用不少的带宽和服务器资源。
而比较新的技术去作轮询的效果是Comet,使用了AJAX。但这种技术虽然可达到双向通讯,但依然须要发出请求,并且在Comet中,广泛采用了长连接,这也会大量消耗服务器带宽和资源。
面对这种情况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通信。git

2.握手协议


在实现websocket连线过程当中,须要透过浏览器发出websocket连线请求,而后服务器发出回应,这个过程一般称为“握手”(handshaking)。为第13版且浏览器为Chrome的例子:github

浏览器请求:web

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: null
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

服务器回应:后端

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Origin: null
Sec-WebSocket-Location: ws://example.com/

3.原理


在请求中的“Sec-WebSocket-Key”是随机的,服务器端会用这些数据来构造出一个SHA-1的信息摘要。
把“Sec-WebSocket-Key”加上一个魔幻字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”。使用SHA-1加密,以后进行BASE-64编码,将结果作为“Sec-WebSocket-Accept”头的值,返回给客户端。api

4.websocket与Socket.IO


WebSocket提供了一个受欢迎的技术,以替代咱们过去几年一直在用的Ajax技术,WebSocket API是下一代客户端-服务器的异步通讯方法,它提供了一个方法能够从客户端使用简单的语法有效地推进消息到服务器。HTML5的WebSocket API:它可用于客户端、服务器端。并且有一个优秀的第三方API,名为Socket.IO。 浏览器

WebSocket API的用法能够参照 认识HTML5的WebSocket
Socket.IO的用法参照官方API socket.io/docs
(ps:官方文档写得不多,但基本的参数配置仍是写出来了,若是看了仍是懵逼的话,建议直接断点进去把Socket的IO对象的属性方法输出来看)


ps:对websocket的初步认识,其实我更倾向于知乎上(做者:董可人)这段通俗易懂的理解:

你能够把 WebSocket 当作是 HTTP 协议为了支持长链接所打的一个大补丁,它和 HTTP 有一些共性,是为了解决 HTTP 自己没法解决的某些问题而作出的一个改良设计。在之前 HTTP 协议中所谓的 keep-alive connection 是指在一次 TCP 链接中完成多个 HTTP 请求,可是对每一个请求仍然要单独发 header;所谓的 polling 是指从客户端(通常就是浏览器)不断主动的向服务器发 HTTP 请求查询是否有新数据。这两种模式有一个共同的缺点,就是除了真正的数据部分外,服务器和客户端还要大量交换 HTTP header,信息交换效率很低。它们创建的“长链接”都是伪.长链接,只不过好处是不须要对现有的 HTTP server 和浏览器架构作修改就能实现。
WebSocket 解决的第一个问题是,经过第一个 HTTP request 创建了 TCP 链接以后,以后的交换数据都不须要再发 HTTP request了,使得这个长链接变成了一个真.长链接。可是不须要发送 HTTP header就能交换数据显然和原有的 HTTP 协议是有区别的,因此它须要对服务器和客户端都进行升级才能实现。在此基础上 WebSocket 仍是一个双通道的链接,在同一个 TCP 链接上既能够发也能够收信息。此外还有 multiplexing 功能,几个不一样的 URI 能够复用同一个 WebSocket 链接。这些都是原来的 HTTP 不能作到的。

2、Socket.IO的使用

1. 直播视频的消息推送


先说说项目背景:公司的app里有直播,相似于新浪app的直播,而“直播后台监控系统”就是为了监控各个主播直播的状况,是否有不当言论等等,目前只有直播的视频画面,没有直播文字,因此须要增长文字监控。
“直播后台监控系统”后端java开发,一个监控页面能够监控4-8个直播间,直播视频采用了腾讯的播放器,传送地址 腾讯云视频点播服务的网页播放器(Web SDK)。 虽然api里有弹幕接口,通过仔细讨论,仍然决定采用Socket.IO来作,而且一个监控页面只创建一个socket连接,监控页面收到推送消息以后根据直播间的id,直接把消息append到对应直播间.

需求和思路说清楚了,如今直接贴代码:

首次先在页面上引入,从源码能够看到,socket.io-1.4.0.js已作了兼容,AMD和CMD规范均可以用,

<script src="http://cdn.socket.io/socket.io-1.4.0.js"></script>

此时,Socket.IO在此页面上是有效的,下面建立Socket而且绑定消息推送,

var socket = io.connect('http://XXX:9092');  //创建socket连接
    socket.on('connect', function () {  //当socket链接成功以后执行function里面的代码.
        socket.emit('registerMonitorRoomEvent', {  //注册监听事件,将须要监听的直播房间好发给后台.
                roomId : roomId
        });
    });
    socket.on('receiveMessageEvent', function (msg) {  //收到后端推送的直播消息.
           liveObj[msg.roomId].onMonitorMessage(msg); //liveObj是前端定义的对象,存储了全部直播间实例,liveObj[msg.roomId]取到了须要推送消息的直播间,再调用该直播间定义好的onMonitorMessage方法接受消息。
    })
    
    //若是须要断开直播,直接socket.disconnect();

是的,前端代码就是这么少。java小白一只,只能勉强看明白后端写了什么,不贴后端代码了。

2. 聊天室。


socket.io官网上的一个demo,服务端采用node,想要快速看到socket.io各个api效果的,此demo最快。项目传送 A simple chat demo for socket.io

ps: examples/chat/public/index.html文件里面的25行,引入的路径要为<script src="/socket.io/socket.io.js"></script>。

3、WebSocket参考资源

维基百科-WebSocket
socket.io官方文档
认识HTML5的WebSocket

相关文章
相关标签/搜索