首页 > 技术文章 > vue 项目中使用socket

liumingwang 2021-01-22 15:24 原文

安装:

cnpm i vue-socket.io -S
cnpm i socket.io-client -S

客户端:

在main.js中

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import VueSocketIO from 'vue-socket.io'
import SocketIO from "socket.io-client"

// socket 连接参数
const socketOptions = {
  autoConnect: false,       // 是否自动连接 如果为false在指定情况下手动触发才连接socket,(this.$socket.open() // 开始连接socket
  path: "/my-app/" // 定义socket后面的路径,不写默认路径为/socket.io
)

// 注册
Vue.use(
  new VueSocketIO({
    debug: true ,   // debug调试,生产关闭
    connection: SocketIO("127.0.0.1:8080", socketOptions)
  })
)

new Vue({
  // 这里为全局监听socket事件消息,不需要全局可以放到组件里面去。
  sockets: {
    connecting() {
      console.log('正在连接')
    },
    disconnect() {
      console.log("Socket 断开");
    },
    connect_failed() {
      cosnole.log('连接失败')
    },
    connect() {
      console.log('连接成功')
    }
  },
  router,
  store,
  render: h => h(App)
}).$mount('#app')

在组件中使用

<template>
  <div id="app">
    <div id="nav">
      <button @click="connect">连接socket</button>
      <button @click="sendMessage">发送数据</button>
    </div>
  </div>
</template>


<script>
export default {
  data() {
    return {

    }
  },

  methods:{

    // 连接socket
    connect() {

      this.$socket.open()       // 开始连接socket
     
      // 仅在组件内订阅事件
      this.sockets.subscribe('welcome', data => {
        console.log('welcome data ', data)
      }) 
      
    },

    // 发送消息
    sendMessage() {
      this.$socket.emit('hello', '客户端')

    }


  },

  sockets:{
    // 
    welcome: data => {
      console.log('welcome data ', data)
    }

  }
}
</script>

  

客户端使用总结

1、全局监听

sockets:{
    welcome: data => {
        console.log('welcome', data)
    }
}

2、组件内监听

this.sockets.subscribe('welcome', data => {
    console.log('welcome', data)
})

注意:监听用的是this.sockets,发送消息是this.$socket 

关于跨域问题:

ocket会存在跨域问题,在生产环境中vue.config.js中配置代理。实际项目中的解决方式还是后端配置跨域问题

vue.config.js配置如下

······

devServer: {
    host: 'localhost',
    port: 8080,
    open: true, //是否自动打开浏览器
    proxy: {
      '/socket.io': {
        target: 'http://172.168.10.24:8100',
        ws: true,
        changeOrigin: true
      }
    }
  }

·····

 

订阅事件记得要取消

socket主要还是用来写聊天室,加入socket房间后要订阅房间内所有的聊天内容,这时如果没有取消之前的订阅事件,下次进入会多次订阅消息。也就是别人只发一条消息,你这边接收到的却是两条甚至多条。哪如何取消订阅呢,我的处理方式是在离开当前聊天页面后,自动取消之前所有的订阅事件。

beforeDestroy() {
        this.sockets.unsubscribe(eventName)
    }

同理,如果是有指定页面才加入socket房间,退出页面时也要记得关闭socket连接。比如你在created中开始连接socket,在beforeDestroy要记得关闭socket,不然下次进入也会连接socket。 

created() {
    this.$socket.open()
    // 查看socket是否连接成功
    this.$socket.connected
}
beforeDestroy() {
    this.$socket.close()
}

  

node服务端参考代码

var http = require('http');
var io = require('socket.io');

// 创建server服务
var server = http.createServer(function (req, res) {
  // 配置socket跨域
  var headers = {};
  headers["Access-Control-Allow-Origin"] = "*";
  headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
  headers["Access-Control-Allow-Credentials"] = true;
  headers["Access-Control-Max-Age"] = '86400'; // 24 hours
  headers["Access-Control-Allow-Headers"] = "X-Requested-With, Access-Control-Allow-Origin, X-HTTP-Method-Override, Content-Type, Authorization, Accept";
  res.writeHead(200, headers);
  res.end();
});

// 启动服务器  监听 1024 端口
server.listen(1024,function() {
	console.log('server runing at 127.0.0.1:1024')
})

// 启动socket服务
var socket = io.listen(server, {origins: '*:*'});

// 监听客户端连接
socket.on('connection',function(socket) {
	console.log('客户端有连接')
	
	// 监听客户端断开
	socket.on('disconnect', () => {
		console.log('客户端断开')
	})
	
	// 给客户端发送消息
	socket.emit('welcome','欢迎连接socket')
    
        // 监听客户端消息
        socket.on('hello', data => {
        	console.log('接收客户端发送数据', data)
        })

});

  

 

  

 

推荐阅读