Чтение и запись Go Channel застряли в бесконечном цикле

Прежде всего, я хочу сделать систему уведомлений Long Polling. Чтобы быть более конкретным, я сделаю http-запрос, и ответ будет возвращен, только если канал карты 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
}

Это блок контроллера:

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();

}

имена функций и переменная, созданные для теста.

Ошибка не возникла. Спасибо за вашу помощь.


person Sinojin    schedule 26.07.2016    source источник
comment
Как вы звоните SetNotification? В вашем коде нет цикла, поэтому, вероятно, это блокирующий канал. Можете ли вы поделиться еще немного кода?   -  person abhink    schedule 26.07.2016
comment
Я добавил код. Как вы думаете, мне нужна петля? код <-MessageNotification["1"] заставляет программу ждать или я ошибаюсь?   -  person Sinojin    schedule 26.07.2016
comment
Как вы вызываете функции Notification и Websocket?   -  person abhink    schedule 26.07.2016
comment
Это контроллер. Я использую beego framework и функцию контроллера обратного вызова beego в соответствии с URL-адресом (например, localhost: 8080/chatinfo)   -  person Sinojin    schedule 26.07.2016
comment
Вы должны добавить тег beego к своему вопросу. Кто-то, кто знает это, может быть в состоянии помочь.   -  person abhink    schedule 26.07.2016


Ответы (1)


Вы не создаете свой канал.

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

Эта строка создает карту с пропускной способностью 10, но вы не создаете фактические каналы на карте. В результате `SetNotification["1"] является нулевым каналом, и отправляет и получает блок нулевых каналов на неопределенный срок.

Вам нужно ввести

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
}

Таким образом, первое местоположение, которое попытается получить доступ к каналу, добавит его на карту и правильно создаст канал, поэтому отправка и получение на нем будут действительно работать.

person Kaedys    schedule 26.07.2016