Redis源码笔记1-客户端

Redis是一个优秀的开源项目,网上下载下来的也都是源程序版本,查看起来也很方便,因此本着学习的精神,尝试阅读其源码,但愿能有所获。html

Redis客户端需求

通常来讲,项目的需求是衡量项目是否完善的标准,对于商业项目来讲,需求是客户提供的,而对于自由项目来讲,这个需求就是本身研究开发的了,需求开发的好坏,与软件质量、开发周期都有关系,因此,在看代码以前,须要捋一捋Redis客户端的开发需求。 Redis是一个内存数据库,跟许多其余的数据库同样,客户端的重要性并非那么高,使用Redis的主要是各类应用程序或网站,通常都会写程序或者调用各类库来链接Redis的服务端,因此服务端的重要性更高。做为一个数据库,其主要的服务端必须具备效率高、可用性高、不易出错等等属性,而对于一个客户端来讲,简洁、友好、简单,让初次接触Redis的用户也不以为头大,让各类服务端提供的功能可以在客户端上显现出来,就能够了。因此,Redis的客户端需求十分简单,主要就是实现各类指令的实现,以及和服务端的交互,而后,最好能有一个友好一些的交互界面就能够了。 ###Linenoise实现 为实现客户端交互更为友好,Redis采用的是Linenoise,一个优秀的命令行提示的c语言库。 Linenoise是Redis的做者开发的另外一个开源项目,实现的功能就是输入几个字符后,在Console中可以显示对应的提示语,以下图,做为一个变成小白来讲,这确实是一个很好玩的功能,因此就学习一下。 redis命令提示示例redis

如图所示,在输入指令“set”后,界面上就显示出一行颜色较淡的提示性文字,这实际上是经过控制输出的字符的颜色来实现的,好比printf("\033[33mhello world\033[m")打印出来的就是黄色的“hello world”,具体颜色和显示效果,参见printf打印带颜色的字体和背景的方法。 但正常状况下,像printf这样的函数打印的只能是一次性的,没法实现对已打印或输出的字符进行编辑,为了实现这个功能,Linenoise采用了更改输入端模式的办法,具体改变以下:数据库

输入端模式修改

这样修改之后,就能够任意更改已输出或输入的字符串了,只是须要注意,显示的全部字符都要本身排列好,否则就显示出一团糟了。我用做者的方法实践了一下,发现效果仍是不错的,测试代码:函数

void getOutLine(char *obuf, char *ibuf, char *hints, char *prompt)
{
	int ilen = strlen(ibuf);
	if(ilen<2 || hints == NULL || strncmp(ibuf, hints, ilen) !=0 )
	{
		sprintf(obuf,"\r%s%s\x1b[0K\r\x1b[%dC",prompt, ibuf,(int)(strlen(prompt)+ilen));
	} else{
		sprintf(obuf,"\r%s%s\x1b[33m%s\x1b[m\x1b[0K\r\x1b[%dC",prompt, ibuf,hints+ilen, (int)(strlen(prompt)+ilen));
	}
}
int main()
{
	char ibuf[32], obuf[128], hints[32], prompt[32];
	char *p = ibuf;
	char c;

	memset(ibuf, 0, 32);
	sprintf(prompt, "redis> ");
	sprintf(hints, "this a test");

	enableRawMode(STDIN_FILENO);
	while(1)
	{
		getOutLine(obuf, ibuf, hints, prompt);
		write(STDOUT_FILENO, obuf, strlen(obuf));
		read(STDIN_FILENO, &c, 1);
		if(c == 13){
			getOutLine(obuf, ibuf, NULL, prompt);
			write(STDOUT_FILENO, obuf, strlen(obuf));
			break;
		} else if(c == 127){
			p--;
			*p = '\0';
			getOutLine(obuf, ibuf, hints, prompt);
			write(STDOUT_FILENO, obuf, strlen(obuf));
		} else {
			*p = c;
			p ++;
		}
	}
	disableRawMode(STDIN_FILENO);
	printf("\n");

	return 0;
}

以上就是主要的实现代码,至于enableRawMode()和disableRawMode()两个函数则是直接从linenoise.c文件里面拷过来的,这里就不贴出来了。须要说明的是,以前说到printf打印出颜色的时候,用的颜色开头标志是“\033”,而linenoise.c里面一概用的是“\x1b”,其实二者是同样的一个是八进制的27一个是十六进制的27。 ###小结 虽然写这一篇笔记大概花了我两小时的时间,写出一个达到本身预期目标的测试程序大概是一天时间,但期间为了读懂整个Linenoise代码,花了我近一个星期,主要是本身水平还不够吧,一看到陌生的有些奇怪的代码,头都大了,之后仍是要多练练。 期间,在写到“c==13”这个地方的时候,我用的是“c=='\n'”,表示换行,结果怎么测试都不行,后来查了源码才明白,我敲的“Enter”键输入的是“\r”,也就是“13”,并非“\n”,哎,习惯换行直接敲“Enter”了,都忘了它的本意就是“光标回到起点”,也就是“\r”。而变量obuf原先给它配的size也跟你们同样是32,结果输入一两个字符之后就冒出稀奇古怪的显示了,一怒之下直接改为obuf[128],这下总算显示正确了。学习