doufanglian7585 2016-12-17 09:30
浏览 100
已采纳

如何确保Redis用户在Go(Golang)中接收消息?

I'm using gin framework to build an API server. In General, I'm build 2 projects. Project 'API' and Project 'SOCKET'. Project 'API' is the main REST API that will used in Android, developed using gin framework (golang). And Project 'SOCKET' is the socket server for client that will use socket connection , using node.js (Socket.IO)

The process begin like this :
User A : as the requester ; A connect to "API"
User B : as the responder ; B connect to "SOCKET"

User A call API requestData from android, the request will handled by "API"'s project. And Project "API" will record the request, and publish on redis as new_request using pubsub

this is the code for example :

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)

}

In Project "SOCKET" there is a subscriber that will listen every publish that occured, and publish new message to channel responseclient this is for the example code :

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

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

}); 

})

This work smoothly, if User B is Connected to Socket.IO. But if User B was offline, or not connected to socket.io, this will waiting for long, until we kill manually or until User B is online

What i am asking for , are :

  1. Can we create something like a callback on redis pub/sub ? If the subscriber doesn't accept the message, due to off line, or something else , we close the connection. Is this possible ?
  2. In Node.Js i know i can use timeout function, that will close the subscribe or emit any event if on certain time, there was no message received, how to do this on golang ? I need to inform the User A if User B is active or offline, so he can wait for a another time to create request.
  3. If nothing can, what is your suggestion for me to do this ?

I hope my question , understandable, and can answered well.
*Some code maybe, missing variable.
** I'm using this library for golang redis : go-redis

  • 写回答

1条回答 默认 最新

  • dongxuan2015 2016-12-17 15:02
    关注

    1) There are no callbacks in Redis.

    2) The usual way to implement a timeout in Go is to use channels and select - where one is a channel where you do the blocking and another channel receives a message on timeout. Examples of that can be found here and here for the docs

    Now for (3), you have some options on methods. The first is to use a list, pushing from one side (publishing) and popping from another (subscribing). For the receiver you wild use BRPOP of BLPOP - blocking pop from right or left respectively. You can combine the two to have persistent messaging.

    Now part of PUBSUB also depends on what you are publishing to. If you are publishing to a channel that would have a subscriber if and only if there is a user connected to receive it (and thus one and only one subscriber to that channel), you can check the response from your publish command. It will tell you how many clients it was published to. If the channel is only subscribed to by an online receiver you would get a '1' back, and a '0' if the user was offline.

    A third example is to store the messages in a sorted set, with the timestamp as the score. This would allow the receiver to connect and get messages from the last time it was connected - but that assumes some persistence of that somewhere - usually the client. You would also need some cleanup activity on the sorted sets.

    Some other things to consider in this scenario is whether you eventually use replication, in which case you have to explicitly account for failovers - though really in the scenario you describe you'd want to account for disconnects and reconnects. There are specific examples of this at my post on reliable PUBSUB.

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

报告相同问题?

悬赏问题

  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?