WebSocket 以及 socket.io 使用

来源:互联网 发布:axure7.0 for mac破解 编辑:程序博客网 时间:2024/05/18 02:43

WebSocket 以及 socket.io 使用

说明

WebSocket 是一个持久化的协议, 是基于HTTP协议的, 它支持长连接,而不是像 ajax 一样通过轮询,每隔一段时间,向服务器发送请求,询问是否有新的信息,服务器端不能主动联系客户端,只能由客户端发起。对于 WebSocket 它只需要一次对服务器的请求,然后服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息,而且跨域通信。

WebSocket API

不同服务器端语言有不同的 API, 一下主要展示客户端API

1. 创建 WebSocket 实例

    const w = new WebSocket('ws://localhost:8181');

‘ws://localhost:8181’ 表示要连接的URL。这个URL应该为响应WebSocket的地址, ws 表示WebSocket协议。

使用“Echo”服务器:ws://echo.websocket.org 能将发送过去的数据返回, 可以用于测试能否链接上

2. 与服务器建立连接后的回调

  • w.onopen = function(){} 成功建立连接
  • w.send() 向服务器发送数据
  • w.close() 关闭 WebSocket 链接或停止正在进行的链接请求
   w.onopen = function(a) {      /*         一旦服务器响应WebSocket 链接请求就会触发open 事件         open事件触发,意味着握手协议结束,WebSocket已经准备好收发数据,         如果你的应用收到open事件,就可以确定服务端已经处理了建立连接的请求,且同意和你的应用通信。      */      console.log('Connect open...');      console.log(w);      /*         发送一个文本消息,在open之后,或者根据WebSocket对象的状态判断是否open      */      w.send('hello websocket');      if (w.readyState === WebSocket.OPEN) {         // 状态码 等于 OPEN 的时候         w.send('is in open');      }      // 状态码      for (let attr in WebSocket) {         console.log(attr, WebSocket[attr]);         /*            CONNECTING   0            OPEN   1            CLOSING   2            CLOSED   3         */       }   }

3. 接受服务器消息的回调

  • w.onmessage = function(){}
    w.onmessage = function (e) {        /*         接收服务器消息触发的事件        */        console.log(e.data); // e.data 服务器返回的数据        console.log(w);        /*         close()用于关闭链接,调用后将不能发送数据        */        w.close();    }

4. 连接失败时触发回调

  • w.onerror = function(){}
    w.onerror = function (e) {        /*         失败时触发,错误会导致链接关闭        */        console.log(e);    }

5. 关闭链接时回调

  • w.onclose = function(){}
    w.onclose = function (e) {        /*         链接关闭时触发        */        console.log('close', e);    }

Socket.io API

Socket.io是一个完全由JavaScript实现、基于Node.js、支持WebSocket的协议用于实时通信、跨平台的开源框架,它除了支持WebSocket通讯协议外,还支持许多种轮询机制以及其它实时通信方式,并封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。会根据浏览器对通讯机制的支持情况,选择最佳方式实现网络实时通信

官网地址 github地址

1. 安装到项目

npm install --save-dev socket.io

2. 服务器端

服务器端API

1. 创建服务
    const app = require('http').createServer(handler);    const io = require('socket.io')(app);    const fs = require('fs');    const ip = require('ip').address();    const DB = require('./db.json');    app.listen(8089, ip);    function handler (req, res) {       fs.readFile(__dirname + '../app/index.html',       function (err, data) {          if (err) {             res.writeHead(500);             return res.end('Error loading index.html');          }          res.writeHead(200);          res.end(data);       });    }    // 客户端就可以通过 `http://${ip}:8089` 建立 websocket 通信了
2. 监听客户端连接
  • socket.on(”, function(data){}) 监听客户端发送的消息
    io.on('connection', function (socket) {       /*            监听客户端连接,回调函数会传递本次连接的socket            回调函数的socket 为一个client与服务器的连接标识,不同client不一样       */        console.log('connection id = ' + socket.id);       socket.on('changeswitch', function (data) {          // 客户端发出的 'changeswitch' 事件的处理函数          console.log(data);       })    })
3. 给客户端发送消息
  • socket.emit(”, {}) 在 connection 回调中使用,将数据传输给对应的客户端
  • socket.broadcast.emit(”, {}) 信息传输对象为所有client,排除当前socket 对应的 client
  • io.socket.emit(”, {}) 信息传输对象为所有client
  • io.sockets.socket(socketid).emit(”, {}) 给指定的客户端发送消息
    io.on('connection', function (socket) {       socket.on('changeswitch', function (data) {          setTimeout(function () {             /*                socket.emit 信息传输对象为当前socket对应的client,各个client socket 互不影响                socket.broadcast.emit 信息传输对象为所有client,排除当前socket 对应的 client                io.socket.emit 信息传输对象为所有client             */             io.sockets.emit('changeswitchfinish', {                success: true,                switchInfo: data             });          }, 500);       })      })

3. 客户端

客户端 API

1. 建立 socket 链接
    import io from 'socket.io-client'; // 注意要引入 -client 的模块否则报错    import ip from './reuqest'; // ip 是通过 webpack 注入的当前 ip 地址,与配置服务器的地址相同    const socket = io(`http://${ip}:8089`);    socket.on('connect', function () {        console.log('链接成功');    })
2. 监听服务器消息
  • socket.on(”, function(data){})
    socket.on('connect',function () {        // 连接成功    })    socket.on('connecting',function () {        // 正在连接    })    socket.on('disconnect',function () {        // 断开连接    })    socket.on('connect_failed',function () {        // 连接失败    })    socket.on('error',function () {        // 报错    })    socket.on('reconnect_failed',function () {        // 重连失败    })    socket.on('reconnect',function () {        // 成功重连    })    socket.on('reconnecting',function () {        // 正在重连    })    socket.on('changeswitchfinish', function (data) {        if (data.success) {            dispatch({type: CHANGE_SWITCH, msg: data})        }     })
3. 向服务器发送消息
  • socket.emit(”, {}) 使用前要确定与服务器是否链接上
    if (socket.connected) {        // statement        socket.emit('changeswitch', {});    }
4. 主动断开链接
  • socket.disconnect()
5. 问题

结合 react redux 一起使用遇到了一些问题,选择了一些折中的解决办法

在发出的 action 中使用 WebSocket,由于不能每一个 action 都打开一个 Socket 服务,所以 最后 socket 挂在了 window 上。

这样由于多个 action 都需要进行 WebSocket 通信,所以不能再 socket.on(‘connect’,fn) 函数中进行 socket.emit() 或者 socket.on(”,fn),解决办法是在每次使用(socket.connected)判断是否连接到服务器,然后发送消息

socket.on(”,fn) 自定义的操作都要在初始化建立 socket 链接后紧接着定义,不要单独定义在某一个 action 中。

0 0
原创粉丝点击