node.js+express+websocket实现服务端推送

一、项目简述

项目中需要服务端主动、连续向客户端推送数据,而http无法满足这一需求,所以使用了websocket

二、websocket

1、websocket简介

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。它使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就形成了一条快速通道,可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,两者之间就直接可以数据互相传送。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

2、http协议与websocket协议

websocket与http

可见,http是客户端发送请求,服务端接受请求并给予回应。而websocket则是在二者之间建立全双工通信信道,由客户端发起建立websocket通信的请求,服务端收到该请求并回应后,双方可进行通信。
WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算)
首先HTTP有 1.1 和 1.0 之说,也就是所谓的 keep-alive ,把多个HTTP请求合并为一个,但是 Websocket 其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解


http与websocket

有交集,但是并不是全部

3、websocket的优点

  • 建立在 TCP 协议之上,服务器端的实现比较容易。
  • 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器
  • 数据格式比较轻量,性能开销小,通信高效
  • 可以发送文本,也可以发送二进制数据
  • 没有同源限制,客户端可以与任意服务器通信
  • 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
    ws://example.com:80/some/path

4、实现

安装socket.io

npm install socket.io socket.io-client --save
1) 客户端

客户端也需要对应引入一个socket.io-clent.js。

import io from 'socket.io-client'
let socket = io("ws://127.0.0.1:8888"); // 建立链接
// 此时会触发后台的connect事件
socket.on('msg',function(data){ // 监听服务端的消息“msg”
    socket.emit('msg', {rp:"fine,thank you"}); //向服务器发送消息
    console.log(data);
});
2)服务端
let express = require('express');
let router = express.Router();
let app = require('express')();
let server = require('http').createServer(app);
let io = require('socket.io')(server);

io.on('connection', function(socket){ // socket相关监听都要放在这个回调里
    console.log('a user connected');
 
    socket.on("disconnect", function() {
        console.log("a user go out");
    });
 
    socket.on("msg", function(obj) {
        //延迟3s返回信息给客户端
        setTimeout(function(){
            console.log('the websokcet message is'+obj);
            io.emit("msg", obj);
        },3000);
    });
});
//开启端口监听socket
server.listen(3001);
 
router.get('/imRoom', function(req, res, next) {
    res.render('im/imRoom');
});
module.exports = router;

因为这个需要对原来的对象进行包装,所以只能写在server中,并且为了和express结合,需要引入http模块并对其进行包装,再传入socket.io进行另一次封装,然后使用server进行监听而不再是app

另外,vue相应的socket客户端有一个vue-socket.io,可以在主文件中引入然后使用vue.use使用,这样在首次创建时就会自动建立连接,因为我这里并不是全部使用Socket,所以没有使用这个包。贴一下代码

import VueSocketIO from "vue-socket-io";
Vue.use(VueSocketIO, "ws://otherserver:8080", {配置项});

然后组件中使用

export default{
  methods: {
    this.$socket.emit('msg',{a:1})` // 发送
  },
  socket: {
    events: {
      changed(msg) { // 监听
                    console.log("Something changed: " + msg);
                }
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容