热爱|记一次使用socket.io的天坑

记一次使用socket.io的天坑 这里是废话(介绍了下socket 和 两个api文档地址) webscoket可以在用户的浏览器和服务器之间打开交互式通信会话。
使用此API,您可以向服务器发送消息并接收事件驱动的响应,无需通过轮询服务器的方式以获得响应
【热爱|记一次使用socket.io的天坑】webscoket文档
还有一个比较细的文章webscoket - socket.io
将webscoket到scoket.io都讲了一遍?
在平常的开发中 也多使用scoket.io居多,因为它解决了很多类似于兼容性的问题。
下面的例子我们也使用它来做。
具体的api还需要看这个中文文档 scoket.io
有几个常用的api

  • on : 监听约定的事件
  • emit : 触发指定的事件
  • broadcast.emit : 事件广播 (广播给除自己以外的所有人)
  • io.to(clientId) : 向指定的人广播
你关心的如何使用? 你们找的跨域无法连接的问题。 可能都是一个问题。
那就是使用后端socket.io的版本太高,或者和前端使用的socket.io-client的版本不匹配。
如果不匹配可能会发生一些奇怪的问题。
我这里说以下我前端和后端的各自使用的版本。
前端: vue3 socket.io-client@1.4.5后端: koa@2.7.0 socket.io@1.4.5

前端如下:
// 终端 npm i socket.io-client@1.4.5

随后我们在vue3种建立一个 io 插件 并且将它注入到全局。
// io.jsimport io from 'socket.io-client'export default {install: (app, { connection, options }) => {const socket = io(connection, options) // 这里是vue3新的全局注入这样你可以在非Setup 中 使用 this.$socket 调用这个io连接。 app.config.globalProperties.$socket = socket // 在setup中 你可以使用Provide / inject 得到socket很简单吧. app.provide('socket', socket) } }

// 在main.js中使用这个插件import SocketIO from 'io.js'import { createApp } from 'vue'import App from './App.vue'createApp.use(SocketIO,{connection: 'http://127.0.0.1:9090/typing' })

// vue3组件中使用// 我们可以使用 provide 和 inject 对。父组件可以作为其所有子组件的依赖项提供程序,而不管组件层次结构有多深。 // 这个特性有两个部分:父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这个数据。import { inject } from "vue"; export const socketIo = () => {// 之前在插件中使用了provide 注入了 socket // 在这里我们需要使用 inject 来获取它 const msgSocket = inject('socket'); // 更新自己数据 msgSocket.on('init', (data) => {console.log(data)}) }

服务端挂载有两种方式
// 方式1// 这种方式将和服务公用一个端口 ,但是需要配置 cors:true 来避免跨域 var http = require('http'); var port = normalizePort(process.env.PORT || '3000'); var server = http.createServer(app.callback()); const io = require('socket.io')(server,{cors:true, serveClient: false, pingInterval: 10000, pingTimeout: 5000, }); server.listen(port); // 方式2 // 直接定义端口 // 目前看没什么不同 const io = require('socket.io')(3000, {cors:true, serveClient: false, // below are engine.IO options pingInterval: 10000, pingTimeout: 5000, cookie: false });

// www文件const app = require('../app'); const debug = require('debug')('demo:server'); const http = require('http'); const port = normalizePort(config.port); const server = http.createServer(app.callback()); const typing = require('../utils/typing'); const io = require('socket.io')(server,{cors:true, serveClient: false, pingInterval: 10000, pingTimeout: 5000, }); typing(io);

// typing.js// 封装了以下游戏的js module.exports = (io) => {const typing = io.of('typing')// 游戏池 let games = { }typing.on('connection', client => {// 每次连接都将连接id 对应为空 if (!games[client.id]) {games[client.id] = null }// 并且广播出去 client.broadcast.emit('userList', { games})client.emit('init', { games})// 检查自己和目标用户是不是已经和别人连接游戏,如果没有就请求连接游戏 client.on("send_request_to_server", (data) => {if (!games[data.clientId] && !games[client.id]) {console.log(data) typing.to(data.clientId).emit('send_request_to_client', {clientId: client.id }); } })// 监听用户点击接受请求 client.on('request_ok_to_server', (data) => {// 建立链接 games[client.id] = data.clientId games[data.clientId] = client.id typing.to(client.id).emit('start') typing.to(data.clientId).emit('start') client.broadcast.emit('userList', { games}) })// 监听清除 client.on('delete_to_server', (data) => {let p2 = games[client.id] if (p2) {typing.to(p2).emit('delete_to_client', data) } })// 监听添加 client.on('push_to_server', (data) => {let p2 = games[client.id] if (p2) {typing.to(p2).emit('push_to_client', data) } })// 断开链接 client.on('disconnect', () => {// 从游戏池种删除自己 delete games[client.id]// 断开与游戏好友的游戏 for (const gamesKey in games) {if (games[gamesKey] === client.id) {games[gamesKey] = null } }client.broadcast.emit('userList', { games})}); }); }

    推荐阅读