Home » Mysql » Connecting directly to Redis with (client side) javascript?

Connecting directly to Redis with (client side) javascript?

Posted by: admin November 29, 2017 Leave a comment

Questions:

Is there a way to directly connect to Redis using client side (not Node.js) javascript?

I’m already using Node.js + PHP + Redis + Socket.io (for the client) successfully for a few projects. However, I really think this could be further simplified to something like PHP + Redis + Browser javascript – taking out the Node.js server which is just another server I’d rather not use if it isn’t necessary. For simple things, I think it would be better to just connect directly to Redis using Javascript.

From what I understand, Redis just serves its request through a port so any language that can make requests to that port would work. In theory, couldn’t you just hit the redis server’s port using client side javascript?

I’m mostly interested in the publish/subscribe functions, which may or may not be possible.

I’m not sure if you can access a non-port 80 port using AJAX, but you technically should be able to forward Redis’ port to port 80 using Nginx reverse proxy or something.

Any ideas? Just a thought. I’m very happy with my current solution, but it doesn’t hurt to wonder if we could do this even better or more efficiently.

Answers:

You can only make HTTP requests with client-side JavaScript and, in some browsers, websockets. However, you should look into Webdis. It adds an easy HTTP/JSON layer to Redis and should do exactly what you want.

Edit: Link fixed.

Questions:
Answers:

The real obstacle is overcoming the non-port 80/443 limitation for the ajax request in the browser; Even with the Webdis solution, because it runs off port 7379 by defaul,t and would conflict with your Apache or Nginx process if ran off port 80.

My advice would be to use the nginx proxy_pass to point to webdis process. You can redirect traffic to port 80 and perform ajax request without the annoying security issues.

Below is a sample NGINX configuration that seems to do the trick for me.

upstream WebdisServerPool 
{
    server 127.0.0.1:7379; #webdis server1
    server 192.168.1.1:7379; #webdis server 2
}


server {

    listen   80; #
    root /path/to/my/php/code/;
    index index.php;
    server_name yourServerName.com;

    location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
            expires max;
            log_not_found off;
    }

    location / {
            # Check if a file exists, or route it to index.php.
            try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME /path/to/my/php/code/$fastcgi_script_name;

    }

    location /redis {

            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            rewrite /(.*)/(.*)/(.*)$ /$2/$3 break; #ignore the /redis
             proxy_redirect off;
            proxy_pass http://webdisServerPool;
    }
}

On the front end side, here is an example of getting all the keys. All redis requests would go through /redis for example:

$.ajax({ 
        url: "/redis/KEYS/*", 
        method: 'GET', 
        dataType: 'json', 
        success:function(data)
        {
            $each(data.KEYS,function(key,value){            
                $('body').append(key+"=>"+value+" <br> ");
            });
        }
});

OR

You could use:

http://wiki.nginx.org/HttpRedis and parse the response yourself.

Questions:
Answers:

I have found that the direct Redis http interfaces don’t work very well with pub/sub or are difficult to set up (at time of writing).

Here is my “workaround” for pub/sub based on the predis examples.

http://bradleygoldsmith.tumblr.com/post/35601539836/quick-and-dirty-redis-subscribe-publish-notifications

Questions:
Answers:

I have a bunch of predefined redis accessors in php, and I use a ‘router’ style function to use them from the client via $.post requests with jQuery. The router is just a big switch:

 public function router() {
$response = array();
switch ($_POST['method']) {
case 'get_whole_list': //is a convenience function with arg $list_key
  if ($_POST['list_key']) {//which will be provided by the POST request data
$response = $this->get_whole_list($_POST['list_key']);
break;
  } else {
$response = (array('error' => 'must be passed with post key "list_key"'));
break;
  } //and so on, until

//it's time to send the response: 
return json_encode(array('response' => $response));
}

and then you just echo $myClass->router()

I access it with jQuery like:

redgets.get_whole_list = function(key, callback) {
    $.post(redgets.router, //points to my php file
       {method: 'get_whole_list', //tells it what to do
       list_key: key}, //provides the required args
       function(data) {
           callback($.parseJSON(data).response); //parses the response
       });

this all works fine; maybe it’s not ideal, but it does make a node.js server redundant.
I am surprised that nobody has already made a general-purpose redis interface in this style.