Flutter-App kann an den UDP-Server im Docker-Container senden, aber keine vom Server gesendeten Daten empfangen. Das bedeutet, dass Sie in einer Flutter-Anwendung das UDP-Protokoll verwenden können, um Daten an einen Server zu senden, der in einem Docker-Container läuft. Wenn der Server jedoch versucht, Daten an die Anwendung zu senden, kann die Flutter-Anwendung die Daten nicht empfangen. Dies kann in einigen spezifischen Anwendungsszenarien zu Einschränkungen führen. Daher müssen Sie bei der Entwicklung von Flutter-Anwendungen darauf achten.
Ich entwickle derzeit einen Backend-UDP-Dienst in Go, der mit einer mobilen Flutter-App kommuniziert.
Dies ist der UDP-Dienstcode:
package main import ( "log" "net" "os" "time" ) func main() { port := ":8080" logger := log.new(os.stdout, "", log.ldate|log.ltime) udp_server, err := net.resolveudpaddr("udp4", port) if err != nil { logger.fatalln(err.error()) return } udp_connection, err := net.listenudp("udp4", udp_server) if err != nil { logger.fatalln(err.error()) return } defer udp_connection.close() buffer := make([]byte, 1024) for { n, addr, err := udp_connection.readfromudp(buffer) if err != nil { udp_connection.writetoudp([]byte("error reading from udp connection"), addr) } buffer_string := string(buffer[0:n]) time_sent := time.now() time_sent_string := time_sent.string() combined_string := buffer_string + time_sent_string data := []byte(combined_string); logger.println(combined_string); _, err = udp_connection.writetoudp(data, addr) if err != nil { logger.fatalln(err.error()) return } } }
Bisher wird der Dienst mit Docker ausgeführt und kann von der Flutter-Anwendung gesendete Daten empfangen, die Anwendung kann jedoch keine vom Server zurückgesendeten Daten empfangen.
Hier sind Flattercode-Schnipsel zum Empfangen und Senden von Nachrichten:
final socket = await rawdatagramsocket.bind(internetaddress.anyipv4, 0).onerror((error, stacktrace) => throw error assocketexception); final server = internetaddress("10.0.2.2"); final port = 8080; final data = [ deviceinfodata.deviceid, datetime.now().toutc().tostring() ]; datetime current = datetime.now(); late datetime responsetime; socket.send(data.tostring().codeunits, server, port); string serverout = ""; socket.listen((event) { final datagram = socket.receive(); if (datagram != null) { // print("data sent to server: ${datagram.data}"); string message = string.fromcharcodes(datagram.data); serverout = message.split("]").last; log(message); socket.close(); } else { socket.close(); } });
Die Docker-Datei des UDP-Dienstes ist:
# Specifies a parent image FROM golang:1.19.2-bullseye # Creates an app directory to hold your app’s source code WORKDIR /app # Copies everything from your root directory into /app COPY . . # Installs Go dependencies RUN go mod download # Builds your app with optional configuration RUN go build -o /udp-go # Tells Docker which network port your container listens on EXPOSE 8080 # Specifies the executable command that runs when the container starts CMD [ "/udp-go" ]
Um es auszuführen, verwende ich den folgenden Befehl:
docker 构建 --rm -t udp-go:alpha .
docker run -d -p 8080:8080/udp --name go-udp udp-go:alpha
Ich verwende /udp
, um den UDP-Port im Container dem 8080-Port auf dem Docker-Host zuzuordnen (https://docs.docker.com/config/containers/container-networking/)
Allerdings kann ich damit nur Daten an den Dienst senden. Ich weiß das, weil die Überprüfung der Docker-Protokolle zeigt, dass der Dienst tatsächlich Daten empfängt. Wenn ich das einfache alte go run
anstelle von Docker zum Ausführen des Dienstes verwenden würde, könnte die Anwendung Nachrichten senden und empfangen. Wie kann ich dieses Problem lösen?
Bearbeiten: Ich habe versucht, expose 8080udp
添加到 dockerfile 而不仅仅是 expose 8080
hinzuzufügen, aber es tritt immer noch der gleiche Fehler auf.
Es stellt sich heraus, dass das Problem hier im Flattercode selbst liegt. Der folgende Codeausschnitt ist ein gültiger Codeausschnitt.
final socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0).onError((error, stackTrace) => throw error asSocketException); final server = InternetAddress("10.0.2.2"); final port = 8080; final data = [ deviceInfoData.deviceId, DateTime.now().toUtc().toString() ]; DateTime current = DateTime.now(); late DateTime responseTime; socket.send(data.toString().codeUnits, server, port); String serverOut = ""; socket.listen((event) { final datagram = socket.receive(); if (datagram != null) { // print("Data sent to server: ${datagram.data}"); String message = String.fromCharCodes(datagram.data); serverOut = message.split("]").last; log(message); } }, onDone: () => socket.close(), );
Bei Verwendung von UDP-Code müssen wir den Socket auf ondone
schließen, anstatt ihn beim Abhören zu schließen, da Dart das Paket möglicherweise nicht vollständig empfangen hat.
Das obige ist der detaillierte Inhalt vonDie Flutter-App kann im Docker-Container an den UDP-Server senden, aber keine vom Server gesendeten Daten empfangen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!