duanmi3476 2019-07-15 13:01
浏览 22
已采纳

Goroutines通讯槽通道仅工作一次

My first attempt to write code in Golang (1.12) with go-routine and channel communication. I have Telegram bot and piece of code which can communicate with bot when some update happened and answer needed. At the same time I try to put some web service which will get a message trough http GET and send it to Bot. And in fact it works, but only once. After it Bot part still working, but http Get request cannot be performed, it hang on till time out.

I try to use channel with buffer, but in this it stops working completely.


//App is a structure with Bot objects
type App struct {
    Router *mux.Router
    Bot
}

//Initialize is method to initialize App session
func (a *App) Initialize() {

    var err error

    a.Bot.BotAPI, err = telegram.NewBotAPI(TelegramBotAPIkey)
    checkErr(err)

    a.Router = mux.NewRouter()
    a.initializeRoutes()
    msgChanel = make(chan string)
}


func (a *App) initializeRoutes() {
    a.Router.HandleFunc("/", a.homePage).Methods("GET")
    a.Router.Path("/message/send").Queries("msg", "{msg}").HandlerFunc(a.getMessage).Methods("GET")
}


}

// Handling of requests to send/message
func (a *App) getMessage(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "-----Send message to Bot-------")
    vars := mux.Vars(r)
    if vars["msg"] != "" {
        fmt.Fprintln(w, vars["msg"])
        msgChanel <- vars["msg"]
    }

// Run is all about running application
func (a *App) Run() {

    var wg sync.WaitGroup
    wg.Add(2)


    go func() {
        defer wg.Done()
        msg := <-msgChanel
        a.Bot.generateAnswer(msgid, msg)
    }()

    go func() {

        var msg string

        defer wg.Done()
        a.Bot.BotAPI.Debug = true

        u := telegram.NewUpdate(0)
        u.Timeout = 60

        updates, err := a.Bot.BotAPI.GetUpdatesChan(u)
        checkErr(err)

        for update := range updates {
            if update.Message == nil {
                continue
            }
            msg = ""
            msgid = update.Message.Chat.ID
            a.Bot.generateAnswer(msgid, msg)
        }
    }()

    log.Fatal(http.ListenAndServe(":8080", a.Router))

    wg.Wait()

}

My problem that there is no error message. I run application and then it is working in terms on Bot communication, but communication with web service happened only once. My first thought was that it is because of of channel blocking, but I send string to channel, then I read it, so it there are should not be any blocking. So my expectation is that each time when I send http GET with message text it will be immediately send to Bot, and system was ready to get next request.

  • 写回答

1条回答 默认 最新

  • dtz46697 2019-07-15 13:26
    关注

    Seems like 'msgChanel' is read only once with 'msg := <-msgChanel'. Channel is blocked and cannot be written into by the HTTP request handler. Maybe you should read channel values with a for loop.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

    报告相同问题?

    悬赏问题

    • ¥80 关于海信电视聚好看安装应用的问题
    • ¥15 vue引入sdk后的回调问题
    • ¥15 求一个智能家居控制的代码
    • ¥15 ad软件 pcb布线pcb规则约束编辑器where the object matpcb布线pcb规则约束编辑器where the object matchs怎么没有+15v只有no net
    • ¥15 虚拟机vmnet8 nat模式可以ping通主机,主机也能ping通虚拟机,但是vmnet8一直未识别怎么解决,其次诊断结果就是默认网关不可用
    • ¥20 求各位能用我能理解的话回答超级简单的一些问题
    • ¥15 yolov5双目识别输出坐标代码报错
    • ¥15 这个代码有什么语法错误
    • ¥15 给予STM32按键中断与串口通信
    • ¥15 使用QT实现can通信