【问题标题】:Go Channel reading and writing stuck in infinite loopGo Channel 读写陷入无限循环
【发布时间】:2016-07-26 23:46:00
【问题描述】:

首先,我想做长轮询通知系统。具体来说,我会发起http请求,只有map channel是true才会返回response。

这是我使用的代码块:

var MessageNotification = make(map[string]chan bool, 10)

func GetNotification(id int, timestamp int) notification {
    <-MessageNotification["1"]

    var chat_services []*models.Chat_service
    o := orm.NewOrm()

    _, err := o.QueryTable("chat_service").Filter("Sender__id", id).RelatedSel().All(&chat_services)

    if err != nil {
        return notification{Status: false}
    }
    return notification{Status: true, MessageList: chat_services}
}

func SetNotification(id int) {
    MessageNotification[strconv.Itoa(id)] <- true
}

这是控制器块:

func (c *ChatController) Notification() {

data := chat.GetNotification(1,0)

c.Data["json"] = data
c.ServeJSON()

  }


func (c *ChatController) Websocket(){


    chat.SetNotification(1)

    c.Data["json"] = "test"
    c.ServeJSON();

}

为测试创建的函数名称和变量。

没有发生错误。感谢您的帮助。

【问题讨论】:

  • 你怎么打电话给SetNotification?您的代码中没有循环,因此它可能是一个阻塞通道。你能再分享一些代码吗?
  • 我添加了代码。你认为我需要循环吗? &lt;-MessageNotification["1"] 代码会让程序等待还是我错了?
  • 如何调用NotificationWebsocket 函数?
  • 这些是控制器。我根据url使用beego框架和beego回调控制器函数。(例如localhost:8080/chatinfo)
  • 您应该将beego标签添加到您的问题中。知道的人可能会提供帮助。

标签: go channel beego


【解决方案1】:

您不是在创建自己的频道。

var MessageNotification = make(map[string]chan bool, 10)

这条线制作了一张容量为 10 的地图,但您并没有在地图中创建实际的通道。结果,`SetNotification["1"] 是一个 nil 通道,并且在 nil 通道上发送和接收无限期阻塞。

你需要输入

MessageNotification["1"] = make(chan bool)

如果需要,您可以包含一个大小(我预感您在地图中的“10”应该是该通道的缓冲)。这甚至可以有条件地完成:

func GetNotification(id int, timestamp int) notification {
    if _, ok := MessageNotification["1"]; !ok { // if map does not contain that key
        MessageNotification["1"] = make(chan bool, 10)
    }

    <-MessageNotification["1"]
    // ...
}

func SetNotification(id int) {
    if _, ok := MessageNotification[strconv.Itoa(id)]; !ok { // if map does not contain that key
        MessageNotification[strconv.Itoa(id)] = make(chan bool, 10)
    }

    MessageNotification[strconv.Itoa(id)] <- true
}

这样,第一个尝试访问通道的位置会将其添加到地图并正确创建通道,因此在其上发送和接收实际上会起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 2013-03-17
    • 2021-02-15
    • 2022-01-23
    相关资源
    最近更新 更多