猿问

如何在同一结构中使用多个通道

在我的代码中,我想执行以下操作:

  1. 从输入接收数据eventmessage

  2. 根据接收到的数据格式化event

我想使用与 OOP 中的方法接近的东西,但看起来我搞砸了。

我写的是:

// Define the structs that contains the channels

type sseData struct {

    event, message string

}

type DataPasser struct {

    data       chan sseData

    logs       chan string

    connection chan struct{} // To control maximum allowed clients connections

}


// DEfine the struct's reciever that do the formating based on the input date

func (p *DataPasser) Format() {

    data := <-p.data

    switch {

    case len(data.event) > 0:

        p.logs <- fmt.Sprintf("event: %v\ndata: %v\n\n", data.event, data.message)

    case len(data.event) == 0:

        p.logs <- fmt.Sprintf("data: %v\n\n", data.message)

    }


}

然后我有以下内容:


func (p *DataPasser) HandleSignal(w http.ResponseWriter, r *http.Request) {

    w.Header().Set("Content-Type", "text/event-stream; charset=utf-8")

    w.Header().Set("Cache-Control", "no-cache")

    w.Header().Set("Connection", "keep-alive")

    setupCORS(&w, r)


    fmt.Println("Client connected from IP:", r.RemoteAddr)


    p.connection <- struct{}{}

    flusher, ok := w.(http.Flusher)

    if !ok {

        http.Error(w, "Internal error", 500)

        return

    }


    fmt.Fprint(w, "event: notification\ndata: Connection to WhatsApp server ...\n\n")

    flusher.Flush()


    // Connect to the WhatsApp client

    go Connect()


    // Prepare dataParser `p` to recieve data through its sseData channel

    go p.Format()



    for {

        select {

        case c := <-p.logs:

            fmt.Fprint(w, c)

            flusher.Flush()

        case <-r.Context().Done():

            <-p.connection

            fmt.Println("Connection closed")

            return

        }

    }

}

阿晨1998
浏览 86回答 2
2回答

FFIVE

当您passer.data从go connect()例程向其发送数据时,例程go p.Format()不在监听。因为您使用的是无缓冲通道parser.data但没有接收器正在监听,所以您的代码被卡住了。要么使用缓冲通道,parser.data要么确保您的例程监听来自数据通道的传入消息已启动,并在实际将数据发送到通道之前进行监听。在你的情况下,我想在Format例程之前开始例程Connect就足够了。

慕虎7371278

我通过写解决了它:&nbsp; &nbsp; // Connect to the WhatsApp client&nbsp; &nbsp; go Connect()&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case data := <-p.data:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("recieved")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case len(data.event) > 0:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(w, "event: %v\ndata: %v\n\n", data.event, data.message)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case len(data.event) == 0:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(w, "data: %v\n\n", data.message)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; flusher.Flush()&nbsp; &nbsp; &nbsp; &nbsp; case <-r.Context().Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <-p.connection&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Connection closed")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }但我仍然对拆分操作和使用接收器感兴趣,我不能接受这个作为答案,因为它是问题的解决方案,但不是问题的答案。任何想法?
随时随地看视频慕课网APP

相关分类

Go
我要回答