Maison >développement back-end >Golang >L'application Flutter peut envoyer au serveur UDP dans le conteneur Docker mais ne peut pas recevoir les données envoyées depuis le serveur
L'application Flutter peut envoyer au serveur UDP dans un conteneur Docker mais ne peut pas recevoir de données envoyées depuis le serveur. Cela signifie que dans une application Flutter, vous pouvez utiliser le protocole UDP pour envoyer des données à un serveur exécuté dans un conteneur Docker. Cependant, lorsque le serveur tente d'envoyer des données à l'application, l'application Flutter ne peut pas recevoir les données. Cela peut entraîner des limitations dans certains scénarios d'application spécifiques, vous devez donc y prêter attention lors du développement d'applications Flutter.
Je développe actuellement un service UDP backend en Go qui communique avec une application mobile Flutter.
Voici le code du service UDP :
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 } } }
Jusqu'à présent, le service fonctionne à l'aide de Docker et peut recevoir des données envoyées par l'application Flutter, mais l'application ne peut pas recevoir de données renvoyées par le serveur.
Voici des extraits de code Flutter pour recevoir et envoyer des messages :
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(); } });
Le fichier docker du service udp est :
# 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" ]
Pour l'exécuter, j'utilise la commande suivante :
docker 构建 --rm -t udp-go:alpha .
docker run -d -p 8080:8080/udp --name go-udp udp-go:alpha
J'utilise /udp
pour mapper le port udp du conteneur au port 8080 de l'hôte docker (https://docs.docker.com/config/containers/container-networking/)
Cependant, cela me permet uniquement d'envoyer des données au service. Je le sais car la vérification des journaux Docker montre que le service reçoit réellement des données. Si je devais exécuter le service en utilisant le bon vieux go run
au lieu d'utiliser Docker, l'application pourrait envoyer et recevoir des messages. Comment puis-je résoudre ce problème?
Edit : j'ai essayé d'ajouter expose 8080udp
添加到 dockerfile 而不仅仅是 expose 8080
mais il y a toujours la même erreur.
Il s'avère que le problème réside ici dans le code Flutter lui-même. L'extrait de code ci-dessous est un extrait de code valide.
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(), );
Lors de l'utilisation du code udp, nous devons fermer le socket sur ondone
plutôt que de fermer le socket pendant l'écoute, car Dart n'a peut-être pas entièrement reçu le paquet.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!