Why does the websocket connection in the JS-PHP bundle fall off when transmitting audio from the microphone?

I'm trying to see the possibilities of transmitting streaming data online via websockets. To begin with, I decided to experiment only with sound, i.e. to implement a kind of voice chat. Since I am most familiar with PHP, I will try to implement the server in this language using Workerman. The essence of the problem: there is a simple client code on JS, which takes the stream from the microphone, cuts it with a recorder and sends it to the server.

var socket = new WebSocket('ws://10.0.0.5:27801/');
    navigator.mediaDevices.getUserMedia({
        audio: true
    })
    .then(function(stream) {
      var $audio = document.getElementById("audio");
      var mediarecorder = new MediaRecorder(stream, {mimeType: "audio/webm; codecs=\"opus\""});
      // send
      mediarecorder.ondataavailable = function(e) {
        if (e.data && e.data.size > 0) {
          socket.send(e.data);
        }
      }
      mediarecorder.start(1000);
});

And there is the simplest server in PHP, which simply sends the received data back.

<?php
include_once(__DIR__."/Workerman/Autoloader.php");

use Workerman\Lib\Timer;
use Workerman\Worker;

$worker = new Worker("websocket://0.0.0.0:27801");

$worker->onConnect = function($c){
    echo "Connected\n";
};

$worker->onMessage = function($c, $data){
    $c->send($data);
};

Worker::runAll();

So if you use this approach to send text, then everything is OK. But in the situation described above, the js connection simply falls off when transmitting data with an error in the connection string

WebSocket connection to 'ws://10.0.0.5:27801/' failed: Could not decode a text frame as UTF-8.

I couldn't Google the solution, I tried changing the connection type on the server. What went wrong in this situation?

Author: Sergey, 2020-10-14

1 answers

I looked at your example. The problem here arises because of the type of frame in the websocket. Workerman sends a text frame by default. JS can see that the frame is text and expects that all characters will be in UTF-8. I don't know how to change it correctly in Workerman. I didn't find it right away in the documentation. It turned out to do this:

$worker->onMessage = function($c, $data){
    $c->websocketType = \Workerman\Protocols\Websocket::BINARY_TYPE_ARRAYBUFFER;
    $c->send($data);
};

I spied the parameter, respectively, in Websocket:: encode (), through which the sent data is passed. What is written in the documentation.

 0
Author: Устьянцев Борис, 2020-10-14 19:07:37