无效的帧头

问题描述 投票:0回答:7

我正在尝试制作实时应用程序。我使用 NodeJS 作为服务器和 Socket.IO,来实现我的实时功能。

问题是我收到的错误为:

 WebSocket connection to 'wss://localhost:1234/socket.io/?EIO=3&transport=websocket' failed: Invalid frame header

我尝试了很多方法,例如将 https 更改为 http、降低 Socket.IO 版本等,但没有任何效果。请帮助我找出问题的原因,以便我可以查明应用程序中的错误。我不想采用其他 COMET 协议。

javascript websocket socket.io
7个回答
17
投票

在服务器和客户端上使用相同版本的

socket.io
socket.io-client


9
投票

这是我的错误,只是我使用 socket.io 初始化服务器两次,这导致了问题


5
投票

对我来说,答案是我正在与版本 2 的客户端连接,而服务器正在运行版本 4。根据 根据文档,我必须在服务器上启用

allowEIO3


2
投票

我遇到的问题是,当使用 create-react-app 并使用“npm run start”运行它以在开发过程中获取实时刷新本地版本时,它默认使用具有

/ws
路径的 websocket。这与我也使用此路径的应用程序发生冲突。因此,当您将
setupProxy.js
与 http-proxy-middleware 一起使用时,它会将两者转发到 api 服务器,这会导致无效的帧标头。

解决方案是在网络应用程序中将 websocket 路由更改为其他类似

/websocket
的内容,并在
setupProxy.js
中进行如下设置:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
    app.use(
        // Do not use `/ws` as it conflicts with create-react-app's hotrefresh socket.
        createProxyMiddleware('/websocket', {
            target: 'http://localhost:3000',
            ws: true,
            changeOrigin: true,
        })
    );
};

1
投票

更改了套接字 io 以使用其独立服务器,它对我有用。最初将其添加到由express创建的服务器中。 这段代码解决了问题..

const io = require("socket.io")();

//listening socket io on different port
io.listen(4000);


0
投票

我目前在使用 socket.io-client 时遇到同样的问题。我按照以下说明解决了我的问题。

您可以尝试在客户端中将 opts.transports 设置为仅 websocket:

io.connect(url, { transports: ['websocket'] }); // default is ['polling', 'websocket']

参考:https://github.com/socketio/socket.io-client/issues/1097#issuecomment-301301030


0
投票

我也遇到了这个问题,但就我而言,我将文件从 javascript 发送到 python 中的 Flask 后端,并且我的块大小太大。似乎 socket.io 将通过网络发送的每帧限制为 1MB,其中包括 socket.io 标头。发送 1MB 或更大的块似乎会弄乱现有的标头,因此我减小了块大小,效果很好。

客户端(与 Socket.io CDN 版本 4.7.5 一起使用的普通 JS)

const form = document.getElementById('main-form')

form.addEventListener('submit', (e) => {
  e.preventDefault();
  const langSelect = document.querySelector('#language');
  const language = langSelect.value;
  const currencySelect = document.querySelector('#currency');
  const currency = currencySelect.value;
  sendFile({ language, currency });
});

const socket = io('http://localhost:5000'); // Adjust the server URL accordingly

function sendFile(moreDataObject) {
  const fileInput = document.getElementById('fileInput');
  const file = fileInput.files[0];
  if (!file) return;

  // if CHUNK_SIZE >= 1MB then the socket header gets overwritten and throws errors
  const CHUNK_SIZE = 1024 * 512; // 0.5MB
  const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
  const fileId = `${file.name}-${Date.now()}`; // Unique ID for the file upload

  for (let i = 0; i < totalChunks; i++) {
    const blob = file.slice(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE);
    const reader = new FileReader();
    reader.onload = (e) => {
      const base64Content = e.target.result.split(',')[1];
      socket.emit('file_chunk', {
        fileId: fileId,
        chunkIndex: i,
        totalChunks: totalChunks,
        chunkData: base64Content,
        fileName: file.name, // Consider sanitizing on the server
        ...moreDataObject // Including the language and currency
      });
    };
    reader.readAsDataURL(blob);
  }
}

服务器(使用 Flask v3.0.2、Flask-Cors v4.0.0、Flask-SocketIO v5.3.6)

import os
from flask import Flask, request
from flask_cors import CORS
from flask_socketio import SocketIO
import base64

app = Flask(__name__)
CORS(app)
socketio = SocketIO(app, cors_allowed_origins="*")

# Dictionary to hold file chunks
file_chunks = {}


@socketio.on("file_chunk")
def handle_file_chunk(data):
    print(f"\n\nLanguage: {data['language']} Currency: {data['currency']}\n\n")
    # Extracting the chunk data
    file_id = data["fileId"]
    chunk_index = data["chunkIndex"]
    total_chunks = data["totalChunks"]
    chunk_data = base64.b64decode(data["chunkData"])
    file_name = data["fileName"]  # Consider sanitizing this

    # Initialize the file's chunk list if not already
    if file_id not in file_chunks:
        file_chunks[file_id] = [None] * total_chunks

    # Store the chunk data
    file_chunks[file_id][chunk_index] = chunk_data

    # Check if all chunks have been received
    if all(chunk is not None for chunk in file_chunks[file_id]):
        upload_path = "uploads"
        if not os.path.exists(upload_path):
            os.makedirs(upload_path)

        # Sanitize the file_name or ensure it's safe before appending it to the path
        safe_file_name = os.path.join(upload_path, os.path.basename(file_name))

        # Reassemble the file
        with open(safe_file_name, "wb") as file:
            for chunk in file_chunks[file_id]:
                file.write(chunk)

        print(f"Received and reassembled {safe_file_name}")

        # Cleanup: remove stored chunks to free memory
        del file_chunks[file_id]


if __name__ == "__main__":
    socketio.run(app)

© www.soinside.com 2019 - 2024. All rights reserved.