因为之前项目涉及到消息推送,所以对实时通信感兴趣,能在实际应用场景中玩出不少花样。
这里给大家说一下全流程,使用socket.io通信分为俩部分
服务器端
服务端基于node使用express框架,我们通过express-generator脚手架构建服务端
npm install -g express-generator // 全局安装 express 脚手架
express myapp
cd myapp
npm install // 安装依赖
//基础依赖安装完成后,我们安装socket.io
npm install socket.io --save
npm start // 启动项目
基本的依赖安装完成,接着我们在bin目录下www文件下导入socket.io模块
var app = require('../app')
var debug = require('debug')('myapp:server')
var http = require('http')
var port = normalizePort(process.env.PORT || '3000')
app.set('port', port)
var server = http.createServer(app)
//socket.io通信,transports这里需要加上websocket,否则会跨域
var io = require('socket.io')(server, { transports: ['websocket'] })
server.listen(port)
server.on('error', onError)
server.on('listening', onListening)
//客户端发起连接时触发
io.on('connection', (socket) => {
//每当一个用户登录,就会生成一个socket对象,此时的socket是对应正连接的客户端对象
//为什么它只会发送给刚连接的用户呢?因为这个socket就是刚连接的用户生成的。
//注意:第一个参数是自己定义的,只要前后端都对应即可
//socket.emit('setId', { id: '123456' })
// setInterval(() => {
// socket.emit('setId', { id: new Date() })
// }, 3000)
//广播api:它会向所有用户发送这个事件。由于它放在“连接”函数里面,所以只要有用户建立连接,就会发送这个事件
//为什么要广播给所有用户呢?当有新用户加入,当然要告知之前的用户,让它们更新“用户列表”,这样新旧用户才能发起聊天
//io.sockets.emit('time', {time:new Date()})
//这是实现单聊的api,使用on监听客户端发来的sendMsgToUser事件
//该事件携带发送的内容,data中有发送者和接收者的id和聊天内容
socket.on('sendMsg', (data) => {
console.log(data)
//给所有用户发送
io.sockets.emit('setId', {id: '1234567'})
//给当前用户发送
//socket.emit('setId', { id: '123456' })
})
})
function normalizePort(val) {
var port = parseInt(val, 10)
if (isNaN(port)) {
// named pipe
return val
}
if (port >= 0) {
// port number
return port
}
return false
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error
}
var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges')
process.exit(1)
break
case 'EADDRINUSE':
console.error(bind + ' is already in use')
process.exit(1)
break
default:
throw error
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address()
var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port
debug('Listening on ' + bind)
}
客户端
同样客户端我们也是通过vue-cli脚手架构建,同时我们还需要安装socket.io-client
npm install -g @vue/cli
vue create app
//选择默认default即可
//安装完成后
cd app
npm install
//安装socket.io-client客户端模块
npm install socket.io-client --save
npm run serve
安装完成后我们处理socket.io-client有俩种方式 在main.js中全局引入socket.io-client
import Vue from 'vue'
import App from './App.vue'
import socketio from 'socket.io-client'
Vue.prototype.$io = socketio('http://localhost:3000', {
transports: ['websocket'],
})
Vue.config.productionTip = false
new Vue({
render: (h) => h(App),
}).$mount('#app')
在页面中调用如下
methods: {
socketMsg() {
//向服务端发送消息
this.$io.emit('sendMsg', { time: new Date() })
//接收服务端相对应的webdata数据
this.$io.on('setId', data => {
this.massage = data.id
})
}
},
mounted() {
this.socketMsg()
}
在需要的页面中引入
<template>
<div class="hello">{{massage}}</div>
</template>
<script>
import socketio from 'socket.io-client' //引入socket.io-client
export default {
name: 'HelloWorld',
props: {
msg: String
},
data() {
return {
massage: ''
}
},
methods: {
socketMsg() {
//因为是本地测试,所以地址是我本地的,这里替换成你们服务的实际地址即可
let io = socketio('http://localhost:3000', {
//transports和服务端统一,否则会跨域
transports: ['websocket']
})
//向服务端发送消息
io.emit('sendMsg', { time: new Date() })
//接收服务端相对应的setId数据
io.on('setId', data => {
this.massage = data.id
})
}
},
mounted() {
this.socketMsg()
}
}
</script>
这就是整个过程
socket.io英文文档