关于socket.io的学习
1.什么是socket.io
socket.io是将WebSocket、AJAX和其它的通信方式全部封装成了统一的通信接口。在使用socket.io的时候,不用担心兼容的问题。
2.socket.io的作用
区别于http只能发送一次请求,socket.io能够保持连接的状态,因此能够实现即时通信的功能,也能应用于网络游戏的数据通信
3. socket.io的使用
3.1 使用场景
可以直接去官网下载socket.io.js 使用,在客户端引用js,实例化socket,即可进行使用(不常用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33<script src="js/socket.io.js" type="text/javascript"></script>
<script>
// 连接绑定好的服务器,在学习\测试中一般选用本地的服务器,在生产发布时,可以不传参数
let socket = io('http://127.0.0.1:3000');
// 监听浏览器对象于服务器建立连接
socket.on('connect',async ()=>{
console.log("与服务器建立起连接");
// 此时可以发送一些网络请求或者其他的操作
});
// 浏览器对象断开连接操作
socket.on('logout',(data)=>{
// 断开连接的操作不能服务器端进行,因为服务端断开连接是将整个socket都断开
// 浏览器(客户端断开的话只是仅仅将当前的客户端,不会影响到其他的客户端)
socket.disconnect()
});
// 想向某人发送信息时,一般的操作为:
// 1. 定义一个对象,里面存放着,发送者,接收者,发送内容
// 2. 将该对象发送至后端服务器,服务器监听到这个内容时,解析该内容,并向接收者发送这个信息
// 值得注意的是,发送内容是通过socket.id进行身份识别并且发送的
// socket.id就是在浏览器对象在连接服务后就会自动生成的
let msg = {
from:mySocketid,
to:theirScocketid,
content:inputData,
time:new Date().getTime()
};
// 将数据提交至服务端
socket.emit('sendMsg',msg);
// 后端服务器会监听该内容,并给对应的socket.id发送该消息
</script>结合后端的服务器进行使用(较为常用)
本次后端服务器的搭建是以node.js的express框架为例:
2.1 在根目录下,创建一个socketio.js的文件(文件命名随意,文件放置的路径随意,之所以选择这样子做是为了放便查找),创建新的js文件可以很好地避开该库对该项目形成太大的依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46//在socketio.js中,此时后端服务器也要安装好socket.io的服务端
//安装方法详见百度或者官网文档
//定义一个空的对象
let socketio = {}
//定义一个函数用于处理socketio的各种业务逻辑
function getSocket(serve){
// 将下载好的socket.io实例化,并载入express生成服务器serve中
socketio.io = require('socket.io')(serve)
let io = socketio1.io;
// 将实例化后的对象,放进先前的空对象中
// 为了方便后续的操作,将先前的对象定义到一个变量中
// 监听连接服务器事件
io.on('connection',function(socket){
// 此处的socket是当前的某个浏览器与服务器的链接对象
// 比如,当我们想广播某个新加入进来的用户时
io.sockets.emit('addUser',{
id:socket.id,
content: "有新用户加入"
});
// 向某个用户发送消息
socket.on('sendMsg',function (data) {
// data = {
// from:'wang',
// to:'ermaizi',
// content:'wang向ermazi发送信息'
// time:1525456335(一个时间戳)
// }
socket.to(data.to).emit('sendClient',data)
});
// 监听添加群聊事件-->指的是当前浏览器加入某个群聊
socket.on('addRoom',function (data) {
console.log(data);
let roomObj = socket.join(data.room);
})
// 监听用户掉线,断开连接事件
// 监听断开连接的操作
socket.on('disconnect',async function () {
console.log(socket.id + '已断开连接');
});
}
}- 在bin/www中挂载上socket对象
1
2
3var server = http.createServer(app);
var socketio = require('../socketio');
socketio.getSocket(server);- 顺带一提,解决前端接口跨域的问题
1
2
3
4
5
6
7
8
9
10
11
12var mySql = require('./module/mysql');// 自己封装的MySQL查询函数
app.get('/api/userlist',async (req, res)=>{
let sqlStr = "select * from user";
let result = await mySql(sqlStr);
// 解决前端跨域的问题
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With');
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
res.json({
data:Array.from(result)
})
});- SQL函数的封装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37const mysql = require('mysql');
//配置连接
const connection = {
host: 'localhost', //主机名,一般是localhost
post: '3306', // 监听的端口号,一般也是3306
user: 'root', // 用户名一般也是根用户名
password: '8848', // 用户密码,安装MySQL时设置的密码
database: 'chat' // 连接的数据库
};
//创建连接对象
let con = mysql.createConnection(connection);
//连接
con.connect(err => {
if (err) {
console.log('数据库连接失败');
} else {
console.log('数据库连接成功');
}
});
//创建promise对象查询方法
function queryFn(sqlStr, arr) {
return new Promise((resolve, reject) => {
con.query(sqlStr, arr, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
module.exports = queryFn;
4. 使用案例
4.1 实现一个网页版即时通信
本次使用的是Vue来搭建前端的框架
用Vue-cli3来创建项目 –> Vue create App(项目名称),为了减少项目的体积,只是想实现socket.io的即时通信,因此并不打算添加路由和VueX
需要安装socket.io的客户端
npm i socket.io-client –save-dev
- 在根目录文件中创建一个全局的socket对象
1 | import io from "socket.io-client" |
在根组件中引用socket.io对象
1
2
3<script>
import socket from '../socket'
</script>在组件挂载后监听与服务器连接的事件
1
2
3
4
5
6
7
8
9
10<script>
export default {
name:'app',
mounted() {
socket.on('connect',async ()=>{
console.log("与服务器建立起连接");
});
}
}
</script>
在通信的组件中添加发送通信的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<template>
<div class="inputcom">
<input type="text" v-model="inputData" @keydown.enter.prevent="sendEvent(inputData)">
<button @click="">发送</button>
</div>
</template>
<script>
import socket from "../../socket"
export default {
name: "chatItem",
data(){
return{
inputData
}
}
methods:{
sendEvent(){
let msg = {
from:this.$root.me,
to:this.touser,
content:this.inputData,
time:new Date().getTime()
};
// 将数据提交至服务端
socket.emit('accept',msg);
}
}
</script>
在根组件中添加接收信息的方法
1
2
3
4
5
6
7
8socket.on('accept',(data)=>{
console.log(data);
// 多加一步判断对方是不是在与当前用户聊天,对方的用户名是否与要发送的用户名一致
if (this.isChat && data.from.username === this.touser.username) {
console.log('已判断成功是这个人');
this.newMsg = data
}
})
4.2 搭建后台的服务器端
本次依旧使用node来搭建后端的服务器
用node的express框架来搭建服务器 –> express –view=ejs serve(服务器名称)
搭建服务器结束之后,安装socket.io的服务端
npm i socket.io(好像是这个,建议百度或者查看官方文档) –save-dev
后面的步骤就和前面预演的一样
5. 总结
socket.io的使用.总的来说就只有以下几种方法
创建socket.io的实例
let socket = io.connect(“http://127.0.0.1:3000"); 前端连接
socketio.io = require(‘socket.io’)(serve); 后端连接
监听socket.io与服务端与客户端的连接
1
2
3socket.on('connect',async ()=>{
console.log("与服务器建立起连接");
});1
2
3socket.on('connection',function(socket){
console.log('已与浏览器建立连接')
}socket发送信息
1
socket.emit('send',{content:'你好呀'})
socket接收信息
1
socket.on('accept',(data)=>{console.log(data)})
socket向某个用户发送信息
1
socket.to(socket.id).emit('sendUser',{content:"wang你好呀"})
socket加入群聊功能
1
socket.on('addRoom',(data)=>{socket.join(data.room)})
监听发送群聊事件,并广播给所有人
1
socket.on('sendMsgRoom',(data)=>{console.log(data.room)})