Rumah >pembangunan bahagian belakang >Golang >Apl Flutter boleh menghantar ke pelayan UDP dalam bekas docker tetapi tidak boleh menerima data yang dihantar daripada pelayan

Apl Flutter boleh menghantar ke pelayan UDP dalam bekas docker tetapi tidak boleh menerima data yang dihantar daripada pelayan

WBOY
WBOYke hadapan
2024-02-09 20:00:09687semak imbas

Apl Flutter boleh menghantar ke pelayan UDP dalam bekas docker tetapi tidak boleh menerima data yang dihantar daripada pelayan

Apl Flutter boleh dihantar ke pelayan UDP dalam bekas docker tetapi tidak boleh menerima data yang dihantar daripada pelayan. Ini bermakna bahawa dalam aplikasi Flutter, anda boleh menggunakan protokol UDP untuk menghantar data ke pelayan yang dijalankan dalam bekas docker. Walau bagaimanapun, apabila pelayan cuba menghantar data kepada aplikasi, aplikasi Flutter tidak boleh menerima data tersebut. Ini boleh menyebabkan pengehadan dalam beberapa senario aplikasi tertentu, jadi anda perlu memberi perhatian kepada perkara ini semasa membangunkan aplikasi Flutter.

Kandungan soalan

Saya sedang membangunkan perkhidmatan udp bahagian belakang dalam perjalanan yang berkomunikasi dengan apl mudah alih flutter.

Ini ialah kod perkhidmatan 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
        }
    }
}

Setakat ini, perkhidmatan ini berjalan menggunakan docker dan boleh menerima data yang dihantar daripada aplikasi flutter, tetapi aplikasi tidak boleh menerima data yang dihantar semula oleh pelayan.

Berikut ialah coretan kod flutter untuk menerima dan menghantar mesej:

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();
  }
});

Fail docker perkhidmatan udp ialah:

# 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" ]

Untuk menjalankannya, saya menggunakan arahan berikut:

  1. docker 构建 --rm -t udp-go:alpha .
  2. docker run -d -p 8080:8080/udp --name go-udp udp-go:alpha

Saya menggunakan /udp untuk memetakan port udp dalam bekas ke port 8080 pada hos docker (https://docs.docker.com/config/containers/container-networking/)

Namun, ini hanya membenarkan saya menghantar data kepada perkhidmatan. Saya tahu ini kerana menyemak log docker menunjukkan bahawa perkhidmatan itu sebenarnya menerima data. Jika saya menggunakan go run lama biasa dan bukannya menggunakan docker untuk menjalankan perkhidmatan, aplikasi boleh menghantar dan menerima mesej. Bagaimanakah saya boleh menyelesaikan masalah ini?

Sunting: Saya cuba menambah expose 8080udp 添加到 dockerfile 而不仅仅是 expose 8080 tetapi ia masih mempunyai ralat yang sama.

Penyelesaian

Ternyata masalah di sini terletak pada kod flutter itu sendiri. Coretan kod di bawah ialah coretan kod yang sah.

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(),
);

Apabila menggunakan kod udp, kita perlu menutup soket pada ondone daripada menutup soket semasa mendengar, kerana dart mungkin belum menerima paket sepenuhnya.

Atas ialah kandungan terperinci Apl Flutter boleh menghantar ke pelayan UDP dalam bekas docker tetapi tidak boleh menerima data yang dihantar daripada pelayan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam