Vue 使用 Vue-socket.io 实现即时聊天应用(连接篇)

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 技术的局限性。

3. socket.io (W3c School):

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.IOSocket.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:根据本篇文章的反响,后续会更新 服务器与客户端的数据交互,客户端如何给服务器发送数据,又是如何接收数据的。有问题而已留言讨论哦。

猜你喜欢

转载自blog.csdn.net/weixin_47746452/article/details/121203029