美文网首页
node.js+express+websocket实现服务端推送

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

作者: 许小花花 | 来源:发表于2019-03-30 23:31 被阅读0次

    一、项目简述

    项目中需要服务端主动、连续向客户端推送数据,而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);
                    }
      }
    }
    

    相关文章

      网友评论

          本文标题:node.js+express+websocket实现服务端推送

          本文链接:https://www.haomeiwen.com/subject/kktebqtx.html