Publishing redis values not working

I have an Actix Websocket that I copied from here and now I want to publish the values of the key data via the websocket. The websocket works and I can upgrade and perform a handshake with a client. However, SET new values to my data key does not show any messages.

use actix_web_actors::ws;

use crate::websocket::websocket::RedisWs;

#[get("/data/collection")]
#[protect(any("ADMIN", "TEACHER", "STUDENT"), error = "access_denied")]
pub async fn data_stream(req: HttpRequest) -> impl Responder {

    let pubsub_stream = RedisCache::subscribe().await;
    let mapped_stream = pubsub_stream.map(|msg| {
        let payload = msg.get_payload_bytes();
        let bytes = bytes::Bytes::copy_from_slice(payload);

        Ok::<bytes::Bytes, PayloadError>(bytes)
    });

    let resp = ws::start(RedisWs {}, &req, mapped_stream);

    resp.unwrap_or_else(|e| HttpError::bad_gateway(e.to_string()).error_response())
}
pub async fn subscribe() -> impl Stream<Item = Msg> { 
        let mut subscribe: PubSub = RedisCache::create_client()
            .get_async_pubsub()
            .await
            .unwrap();
        subscribe.psubscribe("__keyspace@0__:data *").await.unwrap();
        //subscribe.psubscribe("__keyevent@0__:data *").await.unwrap();
        subscribe.into_on_message()
    }

My goal is to see existing and new values in my key data as a client on new and established connections.

Have you enabled keyspace notifications in Redis?

Note that keyspace notifications do not show the updated value of data. It only shows what operation was done on data. So if you want to stream the updated value, you'd need to add in an extra step where, after you received a keyspace event, you retrieve the value of data and stream that to your subscribers.

If only your own application can update the value behind the Redis key, it'd be more efficient to handle the streaming of the updated value to all subscribers in your app logic directly, instead of going through the keyspace notifications for that.

Yes, I have enabled it in the redis.conf.

If only your own application can update the value behind the Redis key, it'd be more efficient to handle the streaming of the updated value to all subscribers in your app logic directly, instead of going through the keyspace notifications for that.

What do you mean with "directly"?

In your app, write the new value to Redis and then broadcast the new value to every subscriber of your app directly, instead of first writing to Redis, then listen for keyspace notifications, receive those, retrieve the value again to only then broadcast that to every subscriber of your app. If no other entity except your app can write to the key you want to listen to, there really is no need to for the complexity of keyspace notifications.

1 Like

Ok, I'll try it.

1 Like