实现即时通讯的几种方式之 socket.io 方式详解

前言

在标准的HTTP协议中,浏览器发起请求,服务器返回一个响应,这意味着在浏览器发起新请求前,服务器不能发送新信息给客户端浏览器;

WebSocket 规范出来之前,开发人员想实现这些实时的 Web 应用,不得不采用一些折衷的方案,其中最常用的就是轮询和 Comet 技术,而 Comet 技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为http流(长连接)。下面我们简单介绍一下这几种技术:

web通讯的几种方式

  • AJAX轮询/短轮询
  • 长轮询
  • http流/长连接
  • websocket
  • socket.io

Ajax轮询/短轮询

Ajax轮询,这是最早的一种实现实时 Web 应用的方案。客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步,服务器收到请求后马上返回响应信息给客户端并关闭连接。。

优点:功能实现简单,程序编写比较容易。
缺点:浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源(每一次的请求和应答都带有完整的HTTP头信息,增加了传输的数据量)。
实例:一般用在实时性要求不高的地方,适用于小型应用。

长轮询

长轮询是服务器收到请求后如果有数据,则立刻响应请求;如果没有数据就会 hold 一段时间,这段时间内如果有数据立刻响应请求;如果时间到了还没有数据,则响应 http 请求;浏览器收到 http 响应后立即再发送一个同样http 请求查询是否有数据。

优点:在无消息的情况下不会频繁的请求,节省了网络流量,耗费资源小。
缺点:服务器端对同一服务器同时http 连接有最大限制,最好同一用户只存在一个长轮询。服务器端没有数据hold连接会消耗资源,需要同时维护多个线程。
实例:WebQQ、Hi网页版、Facebook IM。

短轮询和长轮询,都会hold一段时间,不同的是短轮询是在客户端间隔一段时间发送请求;长轮询是在服务器端hold一段时间返回响应。

http流/长连接

http流也叫长连接,它不同于短轮询和长轮询,指的是在页面整个生命周期内只使用一个HTTP连接,即页面向浏览器发送一个请求,服务器保持tcp连接打开,然后不断向浏览器返回数据。

在http流方式中,使用Forever Iframe (永存的Iframe)技术,该技术涉及了一个置于页面中的隐藏Iframe标签,将这个隐藏的iframe 的src 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端返回数据。

优点:消息即时到达,不发无用的请求;管理起来也相对方便。
缺点:服务器维护一个长连接会增加开销,Iframe标签在浏览器中被逐步取消使用。
实例:Gmail聊天。

Adobe® Flash® Socket

Adobe® Flash® Socket,大部分PC浏览器都支持的socket模式,在页面中嵌入一个使用了Socket类的 Flash程序,javascript通过调用Flash程序提供的Socket接口与服务器端的Socket接口进行通信,javascript在收到服务器端传送的信息后控制页面的显示。

扫描二维码关注公众号,回复: 10398319 查看本文章

优点:实现真正的即时通信,而不是伪即时。
缺点:客户端必须安装Flash插件;非HTTP协议,无法自动穿越防火墙。
实例:网络互动游戏。

Websocket

WebSocket是HTML5规范发布的新协议,和http协议是两个不同的概念,或者说基本没有关系。它们之间唯一的联系点在于,WebSocket在建立握手连接时,数据是通过http协议传输的。但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。

WebSocket实现了一次连接,双方通信的功能。首先由客户端发出WebSocket请求,服务器端进行响应,实现类似TCP握手的动作。这个连接一旦建立起来,就保持在客户端和服务器之间,两者之间可以直接的进行数据的互相传送。

优点:服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。数据格式比较轻量,性能开销小,通信高效。握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
缺点:WebSocket 只有在支持HTML5的浏览器中使用,很多地方需要自己手写,比如断开重连。

点击查看关于WebSocket的详细介绍及使用node.js完成即时通讯案例。

socket.io

Socket.io将Websocket 和轮询 (Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。在支持HTML5的环境下,socket.io 底层的实现机制就是websocket。也就是说,Websocket 仅仅是 Socket.io实现实时通信的一个子集,工作中,优先使用socket.io。

socket.io能实现的功能

  • socket.io可以实现即时通讯和聊天。
  • 可以来回发送任何二进制流的图像/音频和视频。
  • 实现实时数据统计分析。
  • 允许用户同时在线编辑文档并查看彼此的更改。

特点:用法简单、兼容性好、支持跨平台、兼容低版本浏览器,注重可靠性和速度。

socket.io语法

  • 使用emit(eventName,data),发送数据,第一个参数为自定义的事件名称;第二个参数为要发送的数据;
  • 使用on(eventName,fn),接收数据,第一个参数为发送时的事件名称;第二个参数是一个回调函数,它的参数为接收到的数据;
//客户端开启连接
var socket = io('http://localhost:3000');

//服务端开启连接
var server = require('http').createServer();
var socket=require("socket.io")(server);
server.listen(3000);

//发送数据
socket.emit('hello', {name:"xiaoming",age:18});

//接收数据
socket.on('hello', function (data) {
	console.log(data);
	//{name:"xiaoming",age:18}
})

socket.io使用

客户端使用

方式一:
前端html页面中引入js文件, socket.io.js文件 CDN地址:https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js

<script src="./socket.io.js"></script>

方式二:
ES6中可以使用npm install socket.io --save安装socket.io
然后使用 import 导入

import io from 'socket.io-client';

js代码:

//连接服务器端
let socket=io("http://localhost:3000");

//连接成功后,回调函数
socket.on("connect",()=>{
	console.log("connect .....")
})

//通过emit发送消息给服务端
socketio.emit("message",{name:"xiaoming",age:18});

//通过on监听服务器端返回的数据
socket.on("news",(msg)=>{
	console.log(msg); //ok
})

服务端使用

使用nodeJs来写服务端
在终端中执行npm install socket.io --save安装socket.io
使用 require 导入到模块中

var http = require('http');
var server = http.createServer();

//开启socket.io服务
var io=require("socket.io")(server);

//连接成功后,执行回调函数
io.on("connection",(client)=>{
  console.log("connection ...")
})

//发送数据到客户端
socketio.emit("news","ok")

//接收客户端发送过来的数据
socket.on("message",(msg)=>{
	console.log(msg);
	//{name:"xiaoming",age:18}
})

server.listen(3000);
发布了130 篇原创文章 · 获赞 46 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Charissa2017/article/details/105191235