首先,我要制作长轮询通知系统。更具体地说,我将发出http请求,并且仅当map channel 为true时才返回响应。

这是我使用的代码块:

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
}

这是 Controller 块:
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();

}

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

没有发生错误。谢谢你的帮助。

最佳答案

您不是要创建 channel 。

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

这条线制作的 map 容量为10,但您并未在 map 中创建实际的 channel 。结果,“SetNotification [“1”]是一个零 channel ,并且在无限 channel 上无限期地发送和接收。

你需要放
MessageNotification["1"] = make(chan bool)

如果需要,您可以包括一个尺寸(我预感您的 map 制作中的“10”应该是该 channel 的缓冲区)。这甚至可以有条件地完成:
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
}

这样,第一个尝试访问该 channel 的位置会将其添加到 map 中并正确地构成了该 channel ,因此在该 channel 上的发送和接收实际上将起作用。

关于go - Go Channel读写陷入无限循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38586804/

10-16 12:33