Heim >Backend-Entwicklung >Golang >Die Flutter-App kann im Docker-Container an den UDP-Server senden, aber keine vom Server gesendeten Daten empfangen

Die Flutter-App kann im Docker-Container an den UDP-Server senden, aber keine vom Server gesendeten Daten empfangen

WBOY
WBOYnach vorne
2024-02-09 20:00:09687Durchsuche

Die Flutter-App kann im Docker-Container an den UDP-Server senden, aber keine vom Server gesendeten Daten empfangen

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.

Frageninhalt

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:

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

Workaround

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen