用go实现redis服务端

上一篇文章我们用PHP来实现的redis服务端,这次我们用go来实现下,看看会有什么区别。

代码如下:

 // redis_server project main.go
package main

import (
	"strings"
	"bufio"
	"fmt"
	"net"
	"strconv"
)

var kv_data map[string]string

func main() {

	kv_data = make(map[string]string)

	//建立socket,监听端口
	netListen, _ := net.Listen("tcp", ":1215")

	defer netListen.Close()

	fmt.Println("Waiting for clients")

	for {
		conn, err := netListen.Accept()
		if err != nil {
			continue
		}
		fmt.Println("Accept a client")
		go handleConnection(conn)
	}
}

//处理连接
func handleConnection(conn net.Conn) {
	for {
		str := parseRESP(conn)
		switch value := str.(type) {
            case string:
                if len(value) == 0 {
					goto end
				}
				conn.Write([]byte(value))
			case []string:
				if ( value[0] == "SET" ) {
		            key := string(value[1])
		            val := string(value[2])
					kv_data[key] = val
		       		conn.Write([]byte("+OK\r\n"))
		        }else if ( value[0] == "GET" ){
		            key := string(value[1])
					val := string(kv_data[key])
					val_len := strconv.Itoa(len(val))
					str := "$"+val_len+"\r\n"+val+"\r\n"
		            conn.Write([]byte(str))
		        }else{
		            conn.Write([]byte("+OK\r\n"))
		        }
				break
            default:

		}
	}
	end:
	conn.Close()
}

func parseRESP(conn net.Conn) interface{} {
	r := bufio.NewReader(conn)
	line,err := r.ReadString('\n')
	if err != nil {
		return ""
	}
	cmd_type := string(line[0])
    cmd_txt := strings.Trim(string(line[1:]),"\r\n")

	switch cmd_type {
    	case "*":
 			count,_ := strconv.Atoi(cmd_txt)
            var data []string
			//"*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n"
            for i := 0; i < count; i++ {
				line,_ := r.ReadString('\n')
    			cmd_txt := strings.Trim(string(line[1:]),"\r\n")
				c,_ := strconv.Atoi(cmd_txt)
				length := c + 2
				str := ""
	            for length > 0 {
	                block,_ := r.Peek(length)
	                if  length != len(block) {

	                }
					r.Discard(length)
	                str += string(block)
	                length -= len(block)
	            }

            	data = append(data,strings.Trim(str,"\r\n"))
            }
			return data
    	default:
        	return cmd_txt
	}
 }

感兴趣的同学可以压测试对比下和PHP的区别

此条目发表在 网站开发, 网站架构 分类目录,贴了 , 标签。将固定链接加入收藏夹。

评论功能已关闭。