Я создаю виджет, который прослушивает пакеты UDP в сети, а затем соответствующим образом обновляет дочерние виджеты.
Я не уверен, куда поместить код инициализации для сокета. Это работает, когда я помещаю вызов в функцию build(), но я не думаю, что это правильно, так как build будет вызываться несколько раз.
Я попытался создать метод initState, но он никогда не вызывается.
Любые указатели?
Спасибо
import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
void connectAndListen() {
int port = 3001;
// listen forever
RawDatagramSocket.bind(InternetAddress.anyIPv4, port).then((socket) {
socket.listen((RawSocketEvent event) {
if (event == RawSocketEvent.read) {
Datagram? dg = socket.receive();
if (dg == null) return;
final recvd = String.fromCharCodes(dg.data);
/// send ack to anyone who sends ping
if (recvd == "ping") socket.send(Utf8Codec().encode("ping ack"), dg.address, port);
print("$recvd from ${dg.address.address}:${dg.port}");
}
});
});
print("udp listening on $port");
}
@override
Widget build(BuildContext context) {
connectAndListen();
return Scaffold(
appBar: AppBar(
title: const Text('Level Details'),
),
body: Column(children: [
]));
}
}
Я не знаю, что происходит в вашем коде. Но если он работает внутри build
(который определенно может вызываться несколько раз), вы можете использовать его и в initState, но внутри очереди микрозадач.
@override
void initState() {
super.initState();
// Call your method from microtask queue. This will only get called once.
Future.microtask(() {
connectAndListen();
});
// Or better:
Future.microtask(connectAndListen);
}
Спасибо, это работает хорошо. Знаете ли вы, уничтожается ли микрозадача при закрытии виджета, например, когда пользователь нажимает «назад» и виджет открывается?
@P_J Нажатие кнопки «Назад» также является событием, которое будет добавлено после завершения вашей микрозадачи. Таким образом, вам не нужно беспокоиться о том, что его убьют.
Покажите, что вы пробовали при использовании
initState
и остальной части объявления вашего класса.