C# 使用 WebSocket 发送 .wav 文件返回 OperationAborted

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

所以我在 Unity 项目中有一个本地 Node.js 服务器和一个 C# 客户端,我想做的是使用 WebSockets 将 .wav 文件流式传输到同一台机器 (localhost:3000) 中的服务器,但是错误我get 是一个非常模糊的 OperationAborted 错误,它不会告诉我客户端和服务器之间是否存在类型不匹配或我需要修复的其他问题。

我是网络套接字的新手,所以提前谢谢你。

C# 客户端

public class WebSocketController : MonoBehaviour
{
    [SerializeField] private AudioSource microphoneSource;

    private void Start()
    {
        string url = "ws://localhost";
        int port = 3000;
        string filePath = "C:/Users/eduar/AppData/LocalLow/Richard J/Sound Recorder/Audio_2023_04_05_23_47_56_2845.wav";
        const int HEADER_SIZE = 44;
        byte[] requestBytes = ConvertWAVtoByteArray(filePath, microphoneSource, HEADER_SIZE);
        SendHttpRequest(url, filePath, port, requestBytes);
    }

    public string SendHttpRequest(string url, string filePath, int port, byte[] requestBytes)
    {
        string _responseMessage = null;
        Socket _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);

        using (_socket)
        {
            // Create and try to connect a dual-stack socket.
            try
            {
                // Create and connect a dual-stack socket.
                Debug.Log("Connecting to server.");
                _socket.Connect(new Uri(url).Host, port);
            }
            catch (SocketException e)
            {
                Debug.LogError("Could not connect to server: " + e.Message);
            }

            // Create the preBuffer data.
            byte[] preBuf = requestBytes;

            // Create the postBuffer data.
            byte[] postBuf = requestBytes;

            // Try to send the request.
            try
            {
                //Send file to the remote device.
                Debug.Log($"Sending {filePath} with buffers to the host.");

                SocketAsyncEventArgs _socketArgs = new SocketAsyncEventArgs();
                _socketArgs.SetBuffer(requestBytes, 0, requestBytes.Length);
                _socketArgs.Completed += new EventHandler<SocketAsyncEventArgs>(SendCallback);
                _socket.SendAsync(_socketArgs);
            }
            catch (SocketException e)
            {
                Debug.LogError("Could not send http request: " + e.Message + "\n");
            }
            finally 
            {
                // Release the socket.
                _socket.Shutdown(SocketShutdown.Both);
                _socket.Close();
            }
        }

        Debug.Log("Http response: " + _responseMessage);
        return _responseMessage;
    }

    private void SendCallback(object sender, SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            // To stream ou may need to specify some type of state and pass it into the SendHttpRequest method so you don't start sending from scratch again untill whole file is sent
            Debug.Log("Socket could send file sucessfully.");
        }
        else
        {
            Debug.LogError("Socket error: " + e.SocketError);
        }
    }

    private byte[] ConvertWAVtoByteArray(string filePath, AudioSource audioSource, int headerSize)
    {
        //Open the stream and read it back.
        byte[] bytes = new byte[audioSource.clip.samples + headerSize];
        using (FileStream fs = File.OpenRead(filePath))
        {
            fs.Read(bytes, 0, bytes.Length);
        }
        return bytes;
    }
}

JavaScript 服务器

const express = require('express');
const fs = require('fs')
const path = require('path')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server,{maxHttpBufferSize: 1e7})

io.on('connection', function (socket) {
  console.log("headers at connection:")
  console.log(socket.handshake.headers)
  socket.on('audio', async function (msg) {
      console.log("headers on evnt:")
      console.log(socket.handshake.headers)
      var date = new Date(msg.timeMillis);
      await fs.promises.writeFile(path.join(__dirname, "videos", `${date.toString()}.wav`), msg.data, "binary");         
  });
});

server.listen(3000)
console.log("Running on port: "+3000)

javascript node.js c# unity3d websocket
1个回答
0
投票

感谢 daniel-b 和所有其他人。我更改了我的客户端代码以使用 https://github.com/endel/NativeWebSocket,因为 .Net 中的 ClientWebSocket 类不适用于 Unity。我现在收到无法连接到远程服务器错误

为了让这是一款手机游戏,我将录制玩家的麦克风并将流发送到服务器,服务器将以 wav 格式存储它。格式,直到被记录。

C# 客户端

using UnityEngine;
using NativeWebSocket;

namespace DevPenguin.Utilities
{
    public class WebSocketController : MonoBehaviour
    {
        WebSocket websocket;

        // Start is called before the first frame update
        async void Start()
        {
            websocket = new WebSocket("ws://localhost:3000");

            websocket.OnOpen += () =>
            {
                Debug.Log("Connection open!");
            };

            websocket.OnError += (e) =>
            {
                Debug.Log("Error! " + e);
            };

            websocket.OnClose += (e) =>
            {
                Debug.Log("Connection closed!");
            };

            websocket.OnMessage += (bytes) =>
            {
                Debug.Log("OnMessage!");
                Debug.Log(bytes);
            };

            // Keep sending messages at every 0.3s
            InvokeRepeating("SendWebSocketMessage", 0.0f, 0.3f);

            // waiting for messages
            await websocket.Connect();
        }

        void Update()
        {
#if !UNITY_WEBGL || UNITY_EDITOR
            websocket.DispatchMessageQueue();
#endif
        }

        async void SendWebSocketMessage()
        {
            if (websocket.State == WebSocketState.Open)
            {
                // Sending bytes
                await websocket.Send(new byte[] { 10, 20, 30 });

                // Sending plain text
                await websocket.SendText("plain text message");
            }
        }

        private async void OnApplicationQuit()
        {
            await websocket.Close();
        }
    }
}

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