Callback executed when message is received from the server.

        :param ws: Websocket client
        :param message: utf-8 string which we get from the server.
        :param message_type: Message type which is either ABNF.OPCODE_TEXT or ABNF.OPCODE_BINARY
        :param fin: continue flag. If 0, the data continues.

def on_data(self, ws, message, message_type, fin):
        """
        Callback executed when message is received from the server.

        :param ws: Websocket client
        :param message: utf-8 string which we get from the server.
        :param message_type: Message type which is either ABNF.OPCODE_TEXT or ABNF.OPCODE_BINARY
        :param fin: continue flag. If 0, the data continues.
        """

        try:
            json_object = json.loads(message)
        except Exception:
            self.on_error(ws, 'Unable to parse received message.')

        if 'error' in json_object:
            # Only call on_error() if a real error occurred. The STT service sends
            # {"error" : "No speech detected for 5s"} for valid timeouts, configured by
            # options.inactivity_timeout
            error = json_object['error']
            if error.startswith(TIMEOUT_PREFIX):
                self.callback.on_inactivity_timeout(error)
            else:
                self.on_error(ws, error)

        # if uninitialized, receive the initialization response from the server
        elif 'state' in json_object:
            if not self.isListening:
                self.isListening = True
                self.callback.on_listening()
                self.send_audio(ws)
            else:
                # close the connection
                self.callback.on_close()
                ws.close()

        # if in streaming
        elif 'results' in json_object or 'speaker_labels' in json_object:
            hypothesis = ''
            if 'results' in json_object:
                hypothesis = json_object['results'][0]['alternatives'][0][
                    'transcript']
                b_final = (json_object['results'][0]['final'] is True)
                transcripts = self.extract_transcripts(
                    json_object['results'][0]['alternatives'])

                if b_final:
                    self.callback.on_transcription(transcripts)

                self.callback.on_hypothesis(hypothesis)
            self.callback.on_data(json_object)