黑马头条vue2.0项目实战(十)——小智同学

目录

1. WebSocket

2. 使用原生 WebSocket(了解)

3. Socket.IO(了解体验)

3.1 介绍

3.2 基本使用

3.3 总结

4. 小智同学

4.1 准备

4.2 页面布局

4.3 建立连接

4.4 收发消息

4.5 展示消息列表

4.6 消息列表自动滚动到底部


1. WebSocket

  • WebSocket 是一种数据通信协议,也是用于客户端和服务端数据通信,类似于我们常见的 http
  • 既然有 http,为啥还要 WebSocket
  • http 通信是单向的
    • 请求 + 响应
    • 没有请求也就没有响应

初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?

答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。

举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用“轮询”:每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。

轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。

WebSocket 协议在 2008 年诞生,2011 年成为国际标准。所有浏览器都已经支持了。

它的最大特点就是,服务器可以主动向客户端推送信息客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

简单理解:

HTTP 打电话:

  • 我问一句
  • 你回答一句
  • 没有提问就没有回答,即便对方主动给你说话,我也是个聋子听不见

WebSocket 打电话:

  • 双向对话

HTTP 和 WebSocket 通信模型

其他特点包括:

(1)和 HTTP 一样属于应用层协议,也是建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443,并且握手阶段(第 1 次建立连接)采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源跨域限制,客户端可以与任意服务器通信。

  • WebSocket 不是用来代替 HTTP 的,它是用来解决实时通信的业务场景。如果业务不需要实时性,那就没必要使用 WebSocket。
  • WebSocket 也是有资源消耗的,因为它要实时通信,也是需要和服务端保持一定的通信连接。
  • WebSocket 也是需要服务端配合才能使用。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

(7)浏览器专门为 WebSocket 通信提供了一个请求对象 WebSocket

  • XmlHttpRequest 请求对象,发起 HTTP 协议请求

2. 使用原生 WebSocket(了解)

参考文档:

浏览器为 HTTP 通信提供了 XmlHttpRequest 对象,同样的,也为 WebSocket 通信提供了一个通信操作接口:WebSocket。

通信模型:

  • 拨号(建立连接)
  • 通话(双向通信)
  • 结束通话(关闭连接)

怎么查看 WebSocket 请求日志:

  • 朝上的绿色箭头是发出去的消息
  • 朝上的绿色箭头是发出去的消息

3. Socket.IO(了解体验)

3.1 介绍

  • 原生的 WebSocket 使用比较麻烦,所以推荐使用一个封装好的解决方案:socket.io
  • socket.io 提供了服务端 + 客户端的实现
    • 客户端:浏览器
    • 服务端:Java、Python、PHP、。。。。Node.js
  • 对于前端开发者来说,只需要关心她的客户端如何使用即可
  • 注意:Socket.io 必须前后端配套使用
    • 实际工作中,socket.io 已经成为了各大后端开发的 WebSocket 通信主流解决方案
  • GitHub 仓库
  • 官网

Socket.io 和 WebSocket 就好比它就好比 axios 和 XMLHTTPRequest 的关系。

3.2 基本使用

官方的 Hello World:https://socket.io/get-started/chat/。

服务端代码:

var app = require("express")();
var http = require("http").createServer(app);
var io = require("socket.io")(http);

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

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

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

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

客户端代码:

<!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: 0.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>

    <!-- SocketIO 提供了一个客户端实现:socket.io.js -->
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
      // 建立连接,得到 socket 通信对象
      var socket = io();

      socket.on("connect", () => {
        console.log("建立连接成功了");
      });

      $("form").submit(function(e) {
        e.preventDefault(); // prevents page reloading
        socket.emit("chat message", $("#m").val());
        $("#m").val("");
        return false;
      });

      socket.on("chat message", function(msg) {
        $("#messages").append($("<li>").text(msg));
      });
    </script>
  </body>
</html>

3.3 总结

我们只需要关注客户端怎么使用:

  • 怎么建立连接
  • 怎么发送消息
  • 怎么接收消息

客户端使用步骤:

  • 下载引入
    • npm install socket.io-client 或者 yarn add socket.io-client
    • import { io } from "socket.io-client"

  • 建立连接

  • 发送消息
// 发送指定类型的消息
// 数据可以是任何类型
socket.emit("消息类型", 数据);
  • 接收消息
// 消息类型
// 回调函数参数获取消息数据
socket.on("消息类型", data => {
  console.log(data);
});

消息类型由后端给出,他会告诉你收发消息的类型,就好比 HTTP 接口中的请求路径一样。

4. 小智同学

4.1 准备

① 创建 views/user-chat/index.vue 。

② 配置路由:

③ 最后,在我的页面中点击 “小智同学” 跳转到聊天页面:

4.2 页面布局

  • 导航栏

  • 消息列表

  • 发送消息

4.3 建立连接

步骤:

  • 导入
  • 建立连接

① 安装依赖

  • yarn add socket.io-client 或者 npm i socket.io-client

② 在初始化的时候建立连接

  • 接口说明

  • 获取用户token 

4.4 收发消息

4.5 展示消息列表

① 模版绑定

② 聊天消息本地持久化

  • 侦听消息列表数组的改变

4.6 消息列表自动滚动到底部

  • 让聊天的信息列表滚动到底部,这个函数的目的是确保用户始终能够看到最新的内容。

  • scrollTop 是一个属性,用于设置或返回滚动区域顶部的偏移量。

  • scrollHeight 是一个属性,表示滚动区域的整个内容的高度,包括超出视口的部分。

  • 公式:DOM.scrollTop = DOM.scrollHeight
  • 将 scrollTop 设置为 scrollHeight 可以确保滚动区域滚动到内容的最底部。

① 设置聊天消息列表滚动容器,具体操作参考——黑马头条vue2.0项目实战(四)——首页—文章列表——3.6 记住列表的滚动位置

② 让聊天的信息列表滚动到底部

③ 更新视图的时候立即执行一遍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值