封装webscoekts

This commit is contained in:
zhutao
2025-11-19 23:20:51 +08:00
parent 1b28239352
commit 701b99b138
4 changed files with 146 additions and 26 deletions

View File

@@ -0,0 +1,16 @@
///学生视频的模型
class Student {
final String id;
final String name;
final bool cameraOn;
final bool micOn;
final bool muted;
Student({
required this.id,
required this.name,
this.cameraOn = true,
this.micOn = true,
this.muted = true,
});
}

View File

@@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'controls/top_bar.dart';
import 'view/student_item.dart';
import 'view/waiting_start.dart';
import 'viewmodel/students_view_model.dart';
class TRoomPage extends StatefulWidget {
const TRoomPage({super.key});
@@ -14,32 +15,39 @@ class TRoomPage extends StatefulWidget {
class _TRoomPageState extends State<TRoomPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xff2c3032),
appBar: TopBar(),
body: true ? WaitingStart() : Padding(
padding: const EdgeInsets.all(10),
child: Row(
spacing: 15,
children: [
Expanded(
child: StudentItem(),
),
SizedBox(
width: 300,
child: ListView.separated(
itemBuilder: (_, index) {
return SizedBox(
height: 250,
child: StudentItem(),
);
},
separatorBuilder: (_, __) => SizedBox(height: 15),
itemCount: 7,
return ChangeNotifierProvider<StudentsViewModel>(
create: (BuildContext context) {
return StudentsViewModel();
},
child: Scaffold(
backgroundColor: Color(0xff2c3032),
appBar: TopBar(),
body: true
? WaitingStart()
: Padding(
padding: const EdgeInsets.all(10),
child: Row(
spacing: 15,
children: [
Expanded(
child: StudentItem(),
),
SizedBox(
width: 300,
child: ListView.separated(
itemBuilder: (_, index) {
return SizedBox(
height: 250,
child: StudentItem(),
);
},
separatorBuilder: (_, __) => SizedBox(height: 15),
itemCount: 7,
),
),
],
),
),
),
],
),
),
);
}

View File

@@ -0,0 +1,33 @@
import 'package:app/data/models/student.dart';
import 'package:app/websocket/room_websocket.dart';
import 'package:flutter/cupertino.dart';
class StudentsViewModel extends ChangeNotifier {
///学生摄像头列表
List<Student> _students = [];
List<Student> get students => _students;
///websocket管理
late RoomWebSocket _ws;
StudentsViewModel() {
_startRoom();
}
///开始链接房间
void _startRoom() {
_ws = RoomWebSocket();
_ws.connect();
_ws.stream.listen((msg) {
_handleMessage();
});
notifyListeners();
}
///发送命令
void _handleMessage() {
print("监听webscoket传来的事件");
}
}

View File

@@ -0,0 +1,63 @@
import 'dart:async';
import 'dart:io';
import 'package:logger/logger.dart';
Logger logger = Logger();
class RoomWebSocket {
///单例设计模式
RoomWebSocket._();
static final RoomWebSocket _instance = RoomWebSocket._();
factory RoomWebSocket() => _instance;
/// WebSocket和心跳定时器
String url = "";
WebSocket? _socket;
Timer? _heartbeatTimer;
///用 StreamController 分化消息给订阅者
final StreamController<Map<String, dynamic>> _msgController = StreamController.broadcast();
Stream<Map<String, dynamic>> get stream => _msgController.stream;
///开始连接
Future<void> connect() async {
try {
_socket = await WebSocket.connect(url);
//监听消息
_socket!.listen(
(data) {},
onDone: () {},
onError: (_) {
logger.e("连接异常断开");
},
);
//心跳
_heartbeatTimer?.cancel();
_heartbeatTimer = Timer.periodic(Duration(seconds: 15), (_) {
logger.i("发送心跳");
});
} catch (e) {
_reconnect();
}
}
///发送指令
void send() {
_socket!.add("");
}
///连接错误事件
void _reconnect() {
logger.e("连接错误");
Future.delayed(Duration(seconds: 3), connect);
}
void dispose() {
_heartbeatTimer?.cancel();
_socket?.close();
_msgController.close();
}
}