最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - Flutter IOWebSocketChannel connection not upgrading to websocket - Stack Overflow

programmeradmin1浏览0评论

Whenever I try to attempt to connect in the server using websocket, it throws and error that says: Websocket error: WebsocketChannelException: WebSocketException: Connection to 'http://host:port/v2/ws-tracking?first_query=first_value&second_query=second_value# was not upgraded to websocket'.

The server side uses FastAPI as a backend and the router is configured as a websocket. Additionally, this is running on our GCP VM instance as a docker container so I am not sure if there seems to be a problem with the cloud server we are hosting it in.

This is the code block for our flutter mobile app:

import 'package:flutter/material.dart';
import 'package:lifttrack/cam/preview.dart';
import 'package:video_player/video_player.dart';
import 'package:image_picker/image_picker.dart';
import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter/return_code.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:web_socket_channel/io.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'dart:io';
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';

import '../services/api_services.dart'; // a module

class VideoPage extends StatefulWidget {
  final String exerciseType;

  const VideoPage({required this.exerciseType, super.key});

  @override
  _VideoPageState createState() => _VideoPageState();
}

class _VideoPageState extends State<VideoPage> {
  VideoPlayerController? _controller;
  File? _videoFile;
  final ImagePicker _picker = ImagePicker();
  IOWebSocketChannel? _channel;
  final List<Map<String, dynamic>> _annotatedFrames = [];
  final FlutterTts _flutterTts = FlutterTts();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _connectWebSocket();
    });
  }

Future<void> _connectWebSocket() async {
    try {
      // Use cached user data if available
      final user = await ApiService().getCurrentUser();
      final username = user.userName;

      // Construct WebSocket URL with username and exercise_name as query parameters
      final uri = Uri(
        scheme: 'ws', // Use 'wss' for secure connections in production
        host: 'x.x.x.x', // Assume the host exist
        port: xxxx, // Assume is a valid port
        path: '/v2/ws-tracking', // ws endpoint from the FastAPI backend
        queryParameters: {
          'username': username,
          'exercise_name': widget.exerciseType,
        },
      );

      final wsUrl = uri.toString();
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Connecting to WebSocket...')),
      );

      _channel = IOWebSocketChannel.connect(wsUrl);

      _channel?.stream.listen((dynamic data) async {
        if (data != null) {
          try {
            if (data is String) {
              final decodedData = jsonDecode(data);
              if (decodedData is Map && decodedData['type'] == 'analysis') {
                final accuracy = decodedData['accuracy'];
                final suggestions = decodedData['suggestions'];
                final predictedClass = decodedData['predicted_class'];
                
                // Enhanced TTS feedback
                await _speakAnalysisFeedback(accuracy, suggestions, predictedClass);
                
                // Additional TTS for immediate feedback
                await _flutterTts.speak("Starting analysis. Please wait...");
              }
            } else if (data is Uint8List) {
              // Handle binary frame data
              setState(() {
                _annotatedFrames.add({
                  'timestamp': DateTime.now().millisecondsSinceEpoch,
                  'image': data,
                });
              });
            }
          } catch (e) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('Error processing received data: $e')),
            );
          }
        }
      }, onError: (error) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('WebSocket error: $error')),
        );
      }, onDone: () {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('WebSocket connection closed by server')),
        );
      });
    } catch (error) {
      if (error is UnauthorizedException) {
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text('Session Expired'),
              content: Text('Session expired. Please log in again.'),
              actions: [
                TextButton(
                  onPressed: () {
                    Navigator.of(context).pop();
                    Navigator.of(context).pushNamedAndRemoveUntil(
                      '/login',
                      (route) => false,
                    );
                  },
                  child: Text('OK'),
                ),
              ],
            );
          },
        );
        return;
      }
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('WebSocket connection failed: $error')),
      );
    }
  }
}

Currently, I tried to force the connection by adding a header to upgrade the protocol. But hoping to find a permanent solution to this problem. Badly need this project to be finished because this is our thesis.

发布评论

评论列表(0)

  1. 暂无评论