WebSocket和SocketIO总结

WebSocket和SocketIO总结

转载:https://blog.csdn.net/qq_14998435/article/details/80030258

1、WebSocket是什么?

WebScoket是一种让客户端和服务器之间能进行双向实时通信的技术。它是HTML最新标准HTML5的一个协议规范,本质上是个基于TCP的协议,它通过HTTP/HTTPS协议发送一条特殊的请求进行握手后创建了一个TCP连接,此后浏览器/客户端和服务器之间便可以通过此连接来进行双向实时通信。

2、为什么要用WebSocket?

1)一直以来,HTTP协议是无状态、单向通信的,即客户端请求一次,服务器回复一次。如果想让服务器消息及时下发到客户端,需要采用类似于轮询的机制,即客户端定时频繁的向服务器发出请求,这样效率很低,而且HTTP数据包头本身的字节量较大,浪费了大量带宽和服务器资源;

2)为提高效率,出现了AJAX/Comet技术,它实现了双向通信且节省了一定带宽,但仍然需要发出请求,本质上仍然是轮询;

3)新一代HTML标准HTML5推出了WebSocket技术,它使客户端和服务器之间能通过HTTP协议建立TCP连接,之后便可以随时随地进行双向通信,且交换的数据包头信息量很小;

3、如何使用WebSocket?

在支持WebSocket的浏览器中,创建Socket之后,通过onopen、onmessage、onclose、onerror四个事件的实现来处理Socket的响应;

4、WebSocket与HTTP、TCP的关系

WebSocket和HTTP都属于应用层协议,且都是基于TCP的,它们的send函数最终也是通过TCP系统接口来做数据传输。那么WebSocket和HTTP的关系呢?WebSocket在建立握手连接时,数据是通过HTTP协议传输的,但是在连接建立后,真正的数据传输阶段则不需要HTTP协议的参与。它们之间的关系如下图:

5、什么情况下使用WebSocket?

如果游戏需要同时支持手机端、Web端,那毫无疑问应该使用WebSocket,现在各个平台都提供了相应的WebSocket实现。如果游戏不需要支持Web端,且对实时性要求比较高,如多人射击、MMORPG之类,那么使用TCP/UDP结合的原生Socket会比较好。

6、SocketIO

WebSocket是HTML5最新提出的规范,虽然主流浏览器都已经支持,但仍然可能有不兼容的情况,为了兼容所有浏览器,给程序员提供一致的编程体验,SocketIO将WebSocket、AJAX和其它的通信方式全部封装成了统一的通信接口,也就是说,我们在使用SocketIO时,不用担心兼容问题,底层会自动选用最佳的通信方式。因此说,WebSocket是SocketIO的一个子集。

 

 

本教程将创建一个基本的聊天应用。 它几乎不要求你事先了解 Node.JS 或 Socket.IO ,适合所有知识层次的用户。

简介


使用流行的 web 应用技术栈 —— 比如 LAMP (PHP) —— 来编写聊天应用通常是很困难的。它包含了轮询服务器以检测变化,还要追踪时间戳,并且这种实现是比较慢的。

大多数实时聊天系统通常基于 socket 来构建。 Socket 为客户端和服务器提供了双向通信机制。

这意味着服务器可以 推送 消息给客户端。无论何时你发布一条消息,服务器都可以接收到消息并推送给其他连接到服务器的客户端。

web 框架


首先要制作一个 HTML 页面来提供表单和消息列表。我们使用了基于 Node.JS 的 web 框架 express 。 请确保安装了 Node.JS

首先创建一个 package.json 来描述我们的项目。 推荐新建一个空目录 (这里使用 chat-example)。


{
  "name": "socket-chat-example",
  "version": "0.0.1",
  "description": "my first socket.io app",
  "dependencies": {}
}
    

要保存 dependencies 信息, 可以用 npm install --save

npm install --save express@4.15.2

express 已经安装好了。我们现在新建一个 index.js 文件来创建应用。


var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.send('<h1>Hello world</h1>');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});
    

这段代码作用如下:

  1. Express 初始化 app 作为 HTTP 服务器的回调函数 (见第 2 行)。
  2. 定义了一个路由 / 来处理首页访问。
  3. 使 http 服务器监听端口 3000。

运行 node index.js 就可以看到如下画面:

socket.io 快速入门教程——聊天应用

在浏览器中访问 http://localhost:3000

socket.io 快速入门教程——聊天应用2

HTML 服务器


目前在 index.js 中我们是通过 res.send 返回一个 HTML 字符串。 如果我们将整个应用的 HTML 代码都放到应用代码里,代码结构将变得很混乱。 替代的方法是新建一个 index.html 文件作为服务器响应。

现在我们用 sendFile 来重构之前的回调:


app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
    

index.html 内容如下:


<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>
    

现在重启进程 (按 Control+C ,然后再次运行 node index) ,刷新页面显示如下:

socket.io 快速入门教程——聊天应用3

集成 Socket.IO


Socket.IO 由两部分组成:

  • 一个服务端用于集成 (或挂载) 到 Node.JS HTTP 服务器: socket.io
  • 一个加载到浏览器中的客户端: socket.io-client

开发环境下, socket.io 会自动提供客户端。正如我们所见,到目前为止,我们只需要安装一个模块:

npm install --save socket.io

这会安装模块并添加依赖到 package.json。在 index.js 文件中添加该模块:


var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});
    

我们通过传入 http (HTTP 服务器) 对象初始化了 socket.io 的一个实例。 然后监听 connection 事件来接收 sockets, 并将连接信息打印到控制台。

在 index.html 的 </body> 标签中添加如下内容:


<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>
    

这样就加载了 socket.io-client。 socket.io-client 暴露了一个 io 全局变量,然后连接服务器。

请注意我们在调用 io() 时没有指定任何 URL,因为它默认将尝试连接到提供当前页面的主机。

重新加载服务器和网站,你将看到控制台打印出 “a user connected”。
尝试打开多个标签页,可以看到多条信息:

socket.io 快速入门教程——聊天应用4

每个 socket 还会触发一个特殊的 disconnect 事件:


io.on('connection', function(socket){
  console.log('a user connected');
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});
    

你可以多次刷新标签页来查看效果:

socket.io 快速入门教程——聊天应用5

触发事件


Socket.IO 的核心理念就是允许发送、接收任意事件和任意数据。任意能被编码为 JSON 的对象都可以用于传输。二进制数据 也是支持的。

这里的实现方案是,当用户输入消息时,服务器接收一个 chat message 事件。index.html 文件中的 script 部分现在应该内容如下:


<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  $(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
  });
</script>
      

index.js 中打印出 chat message 事件:


io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    console.log('message: ' + msg);
  });
});
    

结果应该如以下视频所示:

 

广播


接下来的目标就是让服务器将消息发送给其他用户。

要将事件发送给每个用户,Socket.IO 提供了 io.emit 方法:

io.emit('some event', { for: 'everyone' });

要将消息发给除特定 socket 外的其他用户,可以用 broadcast 标志:


io.on('connection', function(socket){
  socket.broadcast.emit('hi');
});
    

为了简单起见,我们将消息发送给所有用户,包括发送者。


io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});
    

在客户端中,我们捕获 chat message 事件,并将消息添加到页面中。现在客户端代码应该如下:


<script>
  $(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      $('#messages').append($('<li>').text(msg));
    });
  });
</script>
    

就这样,聊天应用就完成了,大约只有 20 行代码! 最终效果如下:

 

课外练习


下面是一些可以做的优化:

  • 当用户连接和断开连接时广播消息
  • 添加昵称
  • 不要将消息发送给服务器后再返回给发送者,应该在用户按下回车后立即将消息显示到消息列表。
  • 添加 “{用户} 正在输入” 功能
  • 显示在线用户
  • 添加私密消息
  • 分享你的改进!

获取示例


可以从 GitHub 获取

$ git clone https://github.com/socketio/chat-example.git


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值