Vue 使用 Vue-socket.io 实现即时聊天应用(连接篇)
1. 目前比较成熟的实现聊天的技术很多,不过都是封装的web socket。在实际的项目中有这个需求,就查找了相应的文章,发现关于Vue实现聊天的完整叙述的文章少之又少。故写此文章,望帮助到正在探寻的小伙伴,欢迎留言讨论。(PS:包括客户端、服务器端、Vue-socket.io 使用的注意事项、请求跨域问题、400状态码问题的解决等,相信读完会有所收获。)2. 先说说Web Socket:Web
1. 目前比较成熟的实现聊天的技术很多,不过都是封装的web socket。在实际的项目中有这个需求,就查找了相应的文章,发现关于Vue实现聊天的完整叙述的文章少之又少。故写此文章,望帮助到正在探寻的小伙伴,欢迎留言讨论。
(PS:包括客户端、服务器端、Vue-socket.io 使用的注意事项、请求跨域问题、400状态码问题的解决等,相信读完会有所收获。)
2. 先说说Web Socket:Web Socket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。说人话就是建立一次连接,后面通信不需要再次建立连接。这里不谈web Socket技术的实现,说说它的缺点以及不能用在Vue项目中的原因:
2.1 传输的数据比较单一,Websocket 支持的数据类型(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;难以满足实际的开发需求;
2.2 监听、发布的事件比较少;
事件 | 使用 | 描述 |
open | Socket.onopen() | 连接建立时触发 |
message | Socket.onmessage() | 客户端接收服务端数据时触发 |
error | Socket.onerror() | 通信发生错误时触发 |
close | Socket.onclose() | 连接关闭时触发 |
方法 | 描述 |
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
由上可以看出 web Socket 只能通过send发送数据,通过监听 message 接收数据。这便是WebSocket 技术的局限性。
Socket.io是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用。
这句话是官方描述,就是它封装了web Socket技术,并做了一些扩展,更好的实现即时通讯。我们可以看到他的案例,是一个Node服务器,一个index.html,而我们是用的Vue项目,希望通过组件来使用socket.io实现聊天;废话不多说,我们直接看Vue-socket.io的使用以及注意事项。
4. Vue-socket.io
4.1 通过socket.io (W3c School)的案例,我们将服务器端的代码直接复制到项目中:
(当然,前提是要下载相应的模块:http、express、socket.io、file)
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
运行 服务器:可以看到已经启动了。
4.2 接下来就很关键了,不要使用 socket.io(W3c School) 的客户端代码,因为没有用。
4.2.1 在Vue项目中,下载 vue-socket.io 依赖;
npm install vue-socket.io --save
4.2.2 在main.js中引入并使用:
import VueSocketIO from "vue-socket.io";
// 注册并使用Vue-socket.io
Vue.use(
new VueSocketIO({
debug: true, // debug调试,生产建议关闭
connection: "http://localhost:3000"
})
);
connection是你的 socket 服务器地址,上面步骤我们创建了一个 3000端口的socket.io服务器,所以这里就是 http://localhost:3000; 然后运行项目,
npm run serve
打开控制台,查看输出:
报错!
第一:Access to XMLHttpRequest at 'http://localhost:3000' from origin 'http://localhost:8080' has been blocked by CORS policy.(记住这个单词:CORS)
这个说的是:不能从 8080 获取 3000 的数据(跨域)
第二:GET xxxx : 400;这个是服务器的400状态码。我们一个一个问题来解决。
5. Vue-socket.io问题解决:
5.1 跨域:跨域问题,在Vue中,可以通过配置代理服务器实现:
创建vue.config.js文件在根目录下!根目录,与Babel.config.js同级。
module.exports = {
lintOnSave: false, //关闭语法检查
/* 开启代理服务器 */
devServer: {
proxy: {
'/socket': {
target: 'http://localhost:3000',
pathRewrite: {
'^/socket': ''
},
ws: true,
changeOrigin: true
},
}
},
}
代理之后,我们通过代理的地址访问代理服务器:
Vue.use(
new VueSocketIO({
debug: true, // debug调试,生产建议关闭
connection: "/socket"
})
);
将connection换成 ‘/socket’,重启Vue项目:
跨域问题解决。
5.2 400:返回400状态码这个问题,我找了好多资料,都没有结果。疯狂的百度,最后,在Migrating from 2.x to 3.0 | Socket.IO和Socket.IO 3.1.0 | Socket.IO 找到了答案!
大概是版本迭代导致这个问题。于是我们修改一下服务器的代码,添加配置项:
var io = require('socket.io')(http,{
allowEIO3: true,
});
重启服务器:
控制台报错,但是服务器已经能收到用户连接的消息了(这是胜利的曙光!):
后面又去查了相关的文章,终于发现问题所在!!CORS
6. 看报错信息:web socket connection to 'ws://localhost:8080/socket.io',应该是我们的请求地址的问题,就是说跨域问题没有根本解决。跨域除了Vue前端处理,还可以在服务器端解决跨域问题。于是找了官网的说明:Handling CORS | Socket.IO
(自从v3开始,你需要加上面的代码) 于是我们修改配置信息:
var io = require('socket.io')(http,{
allowEIO3: true,
cors: {
origin: "http://localhost:8080",
methods: ["GET", "POST"],
credentials: true
}
});
这个origin 是请求的地址,就是Vue项目的地址。
Access to XMLHttpRequest at 'http://localhost:3000' from origin 'http://localhost:8080' has been blocked by CORS policy.
这个解决办法应和了跨域问题出现时的提示信息一致。
重启服务器与Vue项目:
都正常啦!!!!
这就是在Vue中使用Vue-socket.io实现与服务器的连接。
服务器、客户端、跨域问题、400状态码的解决方案。
tips:根据本篇文章的反响,后续会更新 服务器与客户端的数据交互,客户端如何给服务器发送数据,又是如何接收数据的。有问题而已留言讨论哦。
更多推荐