Зайдите на соединение udp, наберите один раз и отправьте много - PullRequest
0 голосов
/ 08 октября 2019

рассмотрите этот код ниже, это упрощенная версия сервиса. Я запускаю нет. Горутины по мере необходимости в течение их жизненного цикла, и когда они занимаются чем-то, им необходимо отправлять сообщения UDP в заданный пункт назначения.

package main

import (
        "fmt"
        "log"
        "net"
        "time"
)

const (
        udp_dest = "192.168.1.200:514"
)

func main() {
        fmt.Println("Hello")
        message := "this is a test"
        log_message(&message)
        go worker(1)
        go worker(2)
        go worker(3)
        go worker(4)
        time.Sleep(3009 * time.Second)
}

func log_message(message *string) {
        RemoteAddr, err := net.ResolveUDPAddr("udp", udp_dest)
        if err != nil {
                //fmt.Println("Err,  net.ResolveUDPAddr", err)
                return
        }
        conn, err := net.DialUDP("udp", nil, RemoteAddr)
        if err != nil {
                return
        }
        udp_message := fmt.Sprintf("<30> %s", *message)
        Bytes, _ := conn.Write([]byte(udp_message))
        log.Printf("Sent %d Bytes to %s\n", Bytes, udp_dest)
}

func worker(tag int) {
        i := 0
        for {
                worker_message := fmt.Sprintf("Some message from worker%d, loop: %d", tag, i)
                log_message(&worker_message)
                // do some work..
                time.Sleep(300 * time.Second)
                i += 1
        }
}

В моем log_message, каждый раз, когда ему звонят, мы звоним net.DialUDP, что я считаю расточительным. Я пытался поэкспериментировать с глобальными переменными &net.UDPConn и др., Но не смог приступить к работе.

Пожалуйста, покажите, как этого добиться / оптимизировать? Есть только один пункт назначения UDP, и я бы хотел, чтобы демон Dial один раз запускался, а затем просто Write по мере необходимости.

Спасибо!


вот что я получил до сих пор:

package main

import (
        "fmt"
        "log"
        "net"
        "time"
)

const (
        udp_dest = "192.168.1.200:514"
)

var (
        myconn *net.UDPConn
)

func main() {
        fmt.Println("Hello")
        message := "this is a test"
        log_message(&message)
        go worker(1)
        go worker(2)
        go worker(3)
        go worker(4)
        time.Sleep(3009 * time.Second)
}

func log_message(message *string) {

        if myconn == nil {

                fmt.Println("Setting up myconn!")
                RemoteAddr, err := net.ResolveUDPAddr("udp", udp_dest)
                if err != nil {
                        //fmt.Println("Err,  net.ResolveUDPAddr", err)
                        return
                }
                myconn, err = net.DialUDP("udp", nil, RemoteAddr)

                if err != nil {
                        return
                }
        }

        udp_message := fmt.Sprintf("<30> %s", *message)
        Bytes, _ := myconn.Write([]byte(udp_message))
        log.Printf("Sent %d Bytes to %s\n", Bytes, udp_dest)
}

func worker(tag int) {
        i := 0
        for {
                worker_message := fmt.Sprintf("Some message from worker%d, loop: %d", tag, i)
                log_message(&worker_message)
                // do some work..
                time.Sleep(10 * time.Second)
                i += 1
        }
}

1 Ответ

0 голосов
/ 08 октября 2019

Вы почти у цели. Переместите код настройки в функцию и вызовите ее перед запуском goroutines.

func main() {
    if err := setupLog(); err != nil {
        log.Fatal(err)
    }
    fmt.Println("Hello")
    ... same as before
}

func setupLog() error {
    fmt.Println("Setting up myconn!")
    RemoteAddr, err := net.ResolveUDPAddr("udp", udp_dest)
    if err != nil {
        return err
    }
    myconn, err = net.DialUDP("udp", nil, RemoteAddr)
    return err
}

func log_message(message *string) {
    udp_message := fmt.Sprintf("<30> %s", *message)
    Bytes, _ := myconn.Write([]byte(udp_message))
    log.Printf("Sent %d Bytes to %s\n", Bytes, udp_dest)
}

Код в вопросе не работает, потому что на myconn существует гонка данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...