2016-12-17 10 views
1

Я использую gin framework для создания сервера API. В целом, я строю 2 проекта. Проект 'API' и проект 'SOCKET'. Проект 'API' является основным REST API, который будет использоваться в Android, разработанном с использованием рамки gin (golang). И Project 'SOCKET' является сокет-сервер для клиента, который будет использовать сокет-соединение, используя Node.js (Socket.IO)Как обеспечить получение подписчиком подписчика redis в Go (Golang)?

Процесс начинаются так:
Пользователь A: как запрашивающей; A connect to "API"
Пользователь B: как ответчик; B подключается к "SOCKET"

User A вызова API requestData от андроида, то запрос будет обрабатываться "API" «s проекта. И Project "API" будет записывать запрос и опубликовать на Redis в new_request с использованием PubSub

это код, например:

client := redis.NewClient(&redis.Options{ 
    Addr:  "localhost:6379", 
    Password: "", // no password set 
    DB:  0, // use default DB 
}) 

pong, err := client.Ping().Result() 

fmt.Println(pong, err) 

if err !=nil { 
    fmt.Println("err",err); 
} 


pubsub, err := client.Subscribe("responseclient") 
if err !=nil { 
    panic(err) 
} 
defer pubsub.Close() 

err = client.Publish("new_request", "Example New Request").Err() 

if err !=nil { 
    panic(err) 
} 
msg, err :=pubsub.ReceiveMessage() 
if err != nil { 
    panic(err) 
} 

fmt.Println(msg.Channel, msg.Payload) 

}

В проекте "SOCKET" есть абонент, который будет слушать каждая публикация, которая произошла, и опубликовать новое сообщение на канал responseclient это код примера:

ioApp.on ('connection' , function(socket) { 
redisSub.on('new_request', function (channel, message) { 
    console.log(channel + ':' + message); 

    redisPub.publish("responseclient", JSON.stringify(res));  

}); 

})

Эта работа гладко, если пользователь B подключен к Socket.io. Но если Пользователь B был в автономном режиме, или не подключен к Socket.io, это будет долго ждать, пока мы не убить вручную или пока пользователь Б не онлайн

Что я прошу, являются:

  1. Можем ли мы создать что-то вроде callback на redis pub/sub? Если абонент не принимает сообщение, из-за линии или чего-то еще, мы закрываем соединение. Это возможно ?
  2. В Node.Js я знаю, что могу использовать функцию таймаута, которая закроет подписку или испустит какое-либо событие, если в определенное время не было получено сообщение, как это сделать на golang? Мне нужно сообщить User A, если User B активен или находится в автономном режиме, поэтому он может подождать еще раз, чтобы создать запрос.
  3. Если ничего не может, то каково ваше предложение для меня сделать это?

Надеюсь, мой вопрос, понятный и может хорошо ответить.
* Некоторый код может быть, отсутствует переменная.
** Я пользуюсь этой библиотекой для golang redis: go-redis

+1

Для первого вопроса ответ: нет. Http://stackoverflow.com/questions/23675394/redis-publish-subscribe-is-redis-guaranteed-to-deliver-the-message-even-under-m , Посмотрите комментарий Antirez для возможного решения. –

+0

Спасибо за ответ. Ищите ACK, возможно, другое решение для меня. Потому что я жду ответа второго вопроса Хехе: D –

ответ

1

1) В Redis нет обратных вызовов.

2) Обычный способ реализовать тайм-аут в Go - использовать каналы и выбирать - где один канал, где вы делаете блокировку, а другой канал получает сообщение о тайм-ауте.Примеры этого можно найти here и here for the docs

Теперь для (3) у вас есть несколько вариантов методов. Первый - использовать список, нажав с одной стороны (публикацию) и выскакивая из другого (подписываясь). Для получателя вы используете BRPOP из BLPOP - блокирование попса соответственно справа или слева. Вы можете комбинировать эти два, чтобы иметь постоянный обмен сообщениями.

Теперь часть PUBSUB также зависит от того, что вы публикуете. Если вы публикуете канал, который будет иметь абонент , если и только если есть пользователь, подключенный для его получения (и, следовательно, один и только один подписчик на этот канал), вы можете проверить ответ от своей команды публикации. Он расскажет вам, сколько клиентов было опубликовано. Если канал подключен только к онлайн-ресиверу, вы получите «1» назад и «0», если пользователь был в автономном режиме.

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

Некоторые другие вещи, которые следует учитывать в этом сценарии, это то, используете ли вы в конечном итоге репликацию, и в этом случае вам нужно явно учитывать отказоустойчивость - хотя на самом деле в описываемом вами сценарии вы хотите учитывать разъединения и повторное подключение. Существуют конкретные примеры этого на my post on reliable PUBSUB.

+0

Спасибо за ответ. Самый быстрый способ сделать это - сделать выбор на канале. –

 Смежные вопросы

  • Нет связанных вопросов^_^