I'm working on an application where audio data is streamed from an Expo app (React Native) to a Node.js server using socket.io. The server then forwards this audio data to Deepgram for speech-to-text processing. Locally, everything functions as expected: I send audio chunks of length 8192 from the mobile app, and the server receives them with the same length. However, when I deploy my server to Google Cloud Run, the received audio chunk lengths vary and are around 16000 bytes, which is not fixed.
This variation in chunk sizes only happens when the data is transmitted over the internet, not in the local environment. My initial thought is that this inconsistency might be related to how data packets are handled or combined over the network.
I attempted to use socket.io-stream for a more streamlined streaming solution, but it seems incompatible with Expo as it relies on Node.js standard libraries not available in the Expo environment.
Here's a simplified version of my current implementation:
Expo App (Client):
Copy code
import io from 'socket.io-client';
const socket = io('http://myserver.com');
// Function to send audio data
const sendAudioChunk = (audioChunk) => {
const int16Array = new Int16Array(audioChunk);
const buffer = Buffer.from(int16Array.buffer);
socket.emit('audio-chunk', buffer);
};
// Example: sending audio chunks
sendAudioChunk(audioChunk);
Node.js Server:
const server = require('http').createServer();
const io = require('socket.io')(server);
io.on('connection', (socket) => {
socket.on('audio-chunk', (chunk) => {
console.log('Chunk size:', chunk.length);
// Forward chunk to Deepgram
});
});
server.listen(3000);
Questions:
What could be causing the change in audio chunk sizes when the server is deployed to Cloud Run, as opposed to when it's run locally? Are there any best practices or alternative approaches for streaming audio data in this scenario, considering the limitations of the Expo environment? Any insights or suggestions to resolve or debug this issue would be greatly appreciated!
EDIT
The problem was due to Socket.IO not upgrading to WebSocket protocol but instead using HTTP long polling. This happened because my Cloud Run service used HTTPS, but I was connecting via an insecure protocol (HTTP).
Switching to a secure WebSocket connection (wss://) fixed the issue.