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 le conteneur Docker mais ne peut pas recevoir les données envoyées depuis le serveur

WBOY
WBOYavant
2024-02-09 20:00:09687parcourir

Lapplication 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.

Contenu de la question

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 :

  1. docker 构建 --rm -t udp-go:alpha .
  2. 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.

Solution de contournement

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer