基于redis通信协议的客户端RedisServer

redis通信协议

Redis跟据不同的命令进行不同的回复。redis server回复的内容类型通过第一个参数可以判断:

1."+"号开头表示单行字符串的回复 如:+OK

2."-"号开头表示错误的信息回复。 如:-wrong date type

3.":"号开头表示一个整数回复。 如":0\r\n"

4."$"号开头表示一个批量的回复。 如GET mykey 返回$6\r\nfoobar\r\n 其中6为字节数,foobar为实现的字符串数据。

5."*"号开头表示多个批量回复。

在这个新的协议中,所有的发送到redis-server的参数都是二进制安全的,其基本形式如下:
*<参数的个数> CR LF
$<参数1字节数> CR LF
<参数1> CR LF
...
$<参数n字节数> CR LF
<参数n> CR LF
例如命令:set mykey myvalue 相对应的形式应该如下,
*3 CR LF  //三个参数
$3 CR LF  //第一个参数set有三个字节
SET CR LF //参数内容set
$5 CR LF  //第二个参数mykey有五个字节
mykey CR LF //参数二内容 mykey
$7 CR LF  //第三个参数有7个字节
myvalue CR LF //参数三内容 myvalue
字符串形式的结果就是 : "*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n"

RedisServer关键代码

1)建立连接
$socket = fsockopen($host, $port, $errno, $errstr);
		if (!$socket)
		{
			$this->reportError('Connection error: '.$errno.':'.$errstr);
			return false;
		}
		$this->connection = $socket;
2)命令拼接

protected function _send($args)
	{
		$command = '*'.count($args)."\r\n";
		foreach ($args as $arg) $command .= "$".strlen($arg)."\r\n".$arg."\r\n";
		$w = fwrite($this->connection, $command);
		
		$answer = $this->_read_reply();
		if ($answer===false && $this->repeat_reconnected)
		{
			if (fwrite($this->connection, $command))
			{
				$answer = $this->_read_reply();
			}
			$this->repeat_reconnected = false;
		}
		return $answer;
	}

3)解析内容

protected function _read_reply()
	{
		$server_reply = fgets($this->connection);
		if ($server_reply===false)
		{
			if (!$this->connect($this->host, $this->port))
			{
				return false;
			}
			else
			{
				$server_reply = fgets($this->connection);
				if (empty($server_reply))
				{
					$this->repeat_reconnected = true;
					return false;
				}
			}
		}
		$reply    = trim($server_reply);
		$response = null;
		switch ($reply[0])
		{
			/* Error reply */
			case '-':
				$this->reportError('error: '.$reply);
				return false;
			/* Inline reply */
			case '+':
				return substr($reply, 1);
			/* Bulk reply */
			case '$':
				if ($reply=='$-1') return null;
				$response = null;
				$size     = intval(substr($reply, 1));
				if ($size > 0)
				{
					$response = stream_get_contents($this->connection, $size);
				}
				fread($this->connection, 2); /* discard crlf */
				break;
			/* Multi-bulk reply */
			case '*':
				$count = substr($reply, 1);
				if ($count=='-1') return null;
				$response = array();
				for ($i = 0; $i < $count; $i++)
				{
					$response[] = $this->_read_reply();
				}
				break;
			/* Integer reply */
			case ':':
				return intval(substr($reply, 1));
				break;
			default:
				$this->reportError('Non-protocol answer: '.print_r($server_reply, 1));
				return false;
		}
		return $response;
	}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

anssummer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值