«

NodeJs实现WebSocket——express-ws

emer 发布于 2019-6-10 14:01   5195 次阅读     


WebSocket是tcp/ip协议之上的一个Socket协议,是为了解决服务器向浏览器主动推送的场景而生,关于该协议的其它内容,本文不做赘述。今天主要讲述一下使用express-ws在NodeJs中如何实现WebSocket 通讯。


必备知识:

如果不清楚以上内容的请点击以上链接查看相关文档。


基本使用:

要想使用express-ws,首先要安装express以及express-ws:

npm i -S express express-ws 

然后,将上面两个包引入到我们的主模块app.js中,并创建服务:

var express = require('express'); var expressWs = require('express-ws'); var app = express(); 

接下来一部就是最重要的一步了,执行我们引入的expressWs方法将app对象传入:

expressWs(app); 

通过执行以上的方法,会在现有的app实例上绑定websocket协议的封装方法,在调用该方法时,其语法类似express提供的get、post、put等方法:

app.ws('/socketTest', function (ws, req){
    ws.send('你连接成功了')
    ws.on('message', function (msg) { // 业务代码 ...
    })
}) 

回调函数中,我们可以拿到两个参数:

  • ws:websocket实例,该实例可以监听来自客户端的消息发送事件(message事件);
  • req:浏览器请求(request)实例,我们可以通过解析这个对象拿到相应的参数。

ws实例提供了send方法,用于向浏览器socket发送数据。通过监听message事件,我们可以拿到浏览器通过websocket为我们发送的数据。

好了,大功告成。是不是超级简单?


模块化开发

一般在大型应用中,我们不会将所有的代码都写在一个文件中,所以express为我们提供了模块化路由。在模块化路由中,express允许我们创建一个迷你app实例,最后将其挂载于我们的主模块实例上即可。如果我们想单独在module1模块上实现websocket,该怎么办呢?之前在npmjs的文档上没有查到方法,经过一番试验后发现,需要分别在主模块的app以及module1模块的子路由中分别进行绑定,才可以开开心心地在module1中使用ws方法:

// module1.js var express = require('express'); var expressWs = require('express-ws'); var router = express.Router();
expressWs(router);

router
  .ws('/user', function (ws, req){
      ws.on('message', function (msg) { // 业务代码 ...
      })
   })
  .get('/user', function(req, resp) {
  })
  .post('/user', function(req, resp) {
  })
  ...

module.exports = router; 
// app.js var express = require('express'); var expressWs = require('express-ws'); var module1 = require('module1'); var app = express();
expressWs(app);
app.use('/ifc', module1);

app.listen(8080); 

页面代码

将以上的代码通过nodejs启动之后,我们便可以编写前端代码进行测试:

var socket = new WebSocket('ws://localhost:8080/ifc/user');
socket.addEventListener('open', function (event) { console.log('socket is open')
});

socket.addEventListener('message', function (event) { console.log('Message from server', event.data);
}); 

socket实例中send方法,用于向服务器发送数据。close方法用于关闭该socket连接


服务端:

var express = require('express');
 var expressWs = require('express-ws');
  var app = express(); 
  expressWs(app); 
  app.ws('/socketTest', function (ws, req){
    ws.send('你连接成功了')
    ws.on('message', function (msg) { // 业务代码 ...
      console.log('msg',msg)
      ws.send('msg:'+new Date().getTime())
    })
}) 
app.listen(8888); 
客户端:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  test
</body>
<script>
  var socket = new WebSocket('ws://localhost:8888/socketTest');
socket.addEventListener('open', function (event) { console.log('socket is open')
    setInterval(()=>{
      socket.send('getMessage')
    },500)
});

socket.addEventListener('message', function (event) { console.log('Message from server', event.data);
}); 

</script>
</html>

调试的时候看控制台的console.log和network中的ws可以看到交互过程,错误处理需要自己根据实际情况改



链接:https://www.jianshu.com/p/b0700d4162e7