WebSocket 'Connection reset by peer, uri'
У меня есть приложение Flutter, в котором я пытаюсь установить рукопожатие с моим бэкендом django websocket. Однако я получаю следующую ошибку:
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: HttpException: Connection reset by peer, uri = http://myIP:8000/ws/chat_app/44HsUd/
Вот мой Django-код, в котором метод receive никогда не выполняется (оператор print никогда не отображается в терминале)
# consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from .utils import get_room
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['unique_id']
self.room_group_name = f'video_{self.room_name}'
# Join room group
self.room_obj = await database_sync_to_async(get_room)(unique_id=self.room_name)
await (self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
async def disconnect(self, close_code):
# Leave room group
await (self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
async def receive(self, text_data):
# Receive video URL from client
print('test in receive')
text_data_json = json.loads(text_data)
video_url = text_data_json['video_url']
# Broadcast video URL to all clients in room
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'video_url',
'video_url': video_url
}
)
async def video_url(self, event):
# Send video URL to client
video_url = event['video_url']
await self.send(text_data=json.dumps({
'video_url': video_url
}))
Я пытаюсь сделать базовый видеоплеер во Flutter, вот мой код
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
class VideoStreamPage extends StatefulWidget {
final String roomName;
const VideoStreamPage({Key? key, required this.roomName}) : super(key: key);
@override
_VideoStreamPageState createState() => _VideoStreamPageState();
}
class _VideoStreamPageState extends State<VideoStreamPage> {
late WebSocketChannel channel;
TextEditingController urlController = TextEditingController();
@override
void initState() {
super.initState();
channel = IOWebSocketChannel.connect(
'ws://myIP:8000/ws/chat_app/${widget.roomName}/');
}
void _sendUrlToServer() {
String url = urlController.text;
if (url.isNotEmpty) {
channel.sink.add(jsonEncode({'video_url': url}));
urlController.clear();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Video Stream'),
),
body: Column(
children: [
Expanded(
child: StreamBuilder(
stream: channel.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return YoutubePlayer(
controller: YoutubePlayerController(
initialVideoId: snapshot.data['video_url'],
flags: YoutubePlayerFlags(
autoPlay: true,
),
),
showVideoProgressIndicator: true,
);
} else if (snapshot.hasError) {
return Center(
child: Text("Error: ${snapshot.error}"),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: urlController,
decoration: InputDecoration(
hintText: 'Enter YouTube URL',
),
),
),
SizedBox(width: 8),
ElevatedButton(
onPressed: _sendUrlToServer,
child: Text('Send'),
),
],
),
),
],
),
);
}
@override
void dispose() {
channel.sink.close();
super.dispose();
}
}
В моем случае проблема была решена после добавления await
перед self.accept()
. Таким образом, функция connect
выглядела следующим образом :
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['unique_id']
self.room_group_name = f'video_{self.room_name}'
# Join room group
self.room_obj = await database_sync_to_async(get_room)(unique_id=self.room_name)
await (self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
await self.accept()
Я думаю, что метод accept() отвечает за прием WebSocket-соединения от клиента и завершение процесса WebSocket handshake.