Advertisement
Snusmumriken

redis receiver

Aug 12th, 2017
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.37 KB | None | 0 0
  1. local serpent = require'serpent'
  2. local socket = require'socket'
  3.  
  4. local connection = {}
  5. connection.__index = connection
  6.  
  7. connection.default = {timeout = 5, ip = '127.0.0.1', port = 6379}
  8. connection.protocol = socket.tcp4 or socket.tcp
  9.  
  10. function connection:new(ip, port, timeout)
  11.     local o = {}
  12.     o.ip = ip or self.default.ip
  13.     o.port = port or self.default.port
  14.     o.timeout = timeout or self.default.timeout
  15.    
  16.     return setmetatable(o, self)
  17. end
  18.  
  19. function connection:connect()
  20.     if self.tcp then return true end
  21.     self.tcp = self.protocol()
  22.     self.tcp:connect(self.ip, self.port)
  23.     self.tcp:settimeout(self.timeout)
  24.     self.tcp:send'PING\n'
  25.     if self.tcp:receive'*l' == '+PONG' then return true end
  26.    
  27.     self:disconnect()
  28.     return false, 'redis not responded'
  29. end
  30.  
  31. function connection:disconnect()
  32.     if not self.tcp then return end
  33.     self.tcp:close()
  34.     self.tcp = nil
  35. end
  36.  
  37. local cr = {}
  38. connection.receiver = cr
  39.  
  40. -- simple strings
  41. cr['+'] = function(self, data) return data end
  42.  
  43. -- errors
  44. cr['-'] = function(self, data) return false, data end
  45.  
  46. -- bulk strings
  47. cr['$'] = function(self, data)
  48.     local bytes = tonumber(data)
  49.     if not bytes or bytes < 1 then return bytes end
  50.     local res, err = self.tcp:receive(bytes + 2) -- data + \r\n
  51.     return err and false or res:sub(1, -3), err  -- cut \r\n
  52. end
  53.  
  54. -- integers
  55. cr[':'] = function(self, data)
  56.     return tonumber(data)
  57. end
  58.  
  59. -- arrays
  60. cr['*'] = function(self, data)
  61.     local count = tonumber(data)
  62.     if not count then return false, 'I can\'t help ((' end
  63.     local list = {}
  64.     for i = 1, count do
  65.         list[i] = self:receive()
  66.     end
  67.     return list
  68. end
  69.  
  70. function connection:receive()
  71.     local res, err = self.tcp:receive'*l'
  72.     if not res then return self.disconnect(), err end
  73.     local head, tail = res:sub(1, 1), res:sub(2)
  74.     return self.receiver[head](self, tail)
  75. end
  76.  
  77. function connection:request(command, close)
  78.     if not self:connect() then return end
  79.    
  80.     self.tcp:send(command..'\r\n')
  81.     return self:receive()
  82. end
  83.  
  84. if not ... then
  85.     c = connection:new()
  86.  
  87.     local test_case = {
  88.         'keys home*',
  89.         'type home:1',
  90.         'hgetall home:id1',
  91.         'get home:1'
  92.     }
  93.  
  94.     for i, v in ipairs(test_case) do
  95.         local res, err = c:request(v)
  96.         local tp = type(res)
  97.         if not res then res = '--ERROR '..tostring(err) end
  98.         res = type(res) == 'table' and serpent.block(res) or tostring(res)
  99.         print('REQUEST ['..v..'] : ('..tp..') '..res)      
  100.     end
  101. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement