• 租房项目 获取地区信息服务


    流程

    获取地域信息流程

    接口

    # Request: 
    method: GET
    url: api/v1.0/areas
    # data:
    no input data
    
    # Response:
    # 返回成功
    {
        "errno": 0,
        "errmsg": "ok",
        "data": [
            {"aid": 1, "aname": "东城区"},
            {"aid": 2, "aname": "西城区"},
            ...
        ]
    }
            
    # 返回失败
    {
    	"errno": "400x", // 状态码
        "errmsg": "状态错误信息"
    }
    

    创建命令

    $ micro new --type "srv" ihome/GetArea
    

    修改名称 example.protogetarea.proto,上一级文件夹名称也由 example 改为 getarea

    lpgit@lpgit-virtual-machine:~/go/src/ihome/GetArea/proto$ tree
    .
    └── getarea
        └── getarea.proto
    
    1 directory, 1 files
    

    Redis 的安装

    具体 Redis 的安装与使用, 请查看此文章: Redis 简介与安装

    安装 Redis

    下载

    $ wget http://download.redis.io/releases/redis-6.0.5.tar.gz
    

    或者进入网址下载指定版本: http://download.redis.io/releases/

    解压

    $ tar xzf redis-6.0.5.tar.gz
    

    进入

    $ cd redis-6.0.5
    

    编译

    $ make
    

    安装

    $ sudo make install
    

    验证

    $ redis-cli
    Could not connect to Redis at 127.0.0.1:6379: Connection refused
    not connected> 
    

    image.png

    启动 Redis

    将 redis 安装包中的 redis.conf 文件复制到项目中 ihome 服务的 conf 文件夹当中

    然后, 修改 redis.conf 文件

    # 69 行左右
    bind 127.0.0.1 当前主机ip
    # 136 行左右修改为 yes,表示守护进程启动
    daemonize yes
    

    在 ihome 服务中创建一个启动文件

    $ sudo vim server.sh
    

    文件内容

    redis-server ./conf/redis.conf
    

    给文件赋予启动权限

    $ chmod 777 server.sh
    

    安装 Go语言的 Redis api 驱动

    $ go get -v -u github.com/gomodule/redigo/redis
    $ go get -v -u github.com/garyburd/redigo
    

    安装 beego 的 cache 缓存模块

    $ go get -v -u github.com/astaxie/beego/cache
    

    编写 ptoro 文件

    syntax = "proto3";
    
    package go.micro.srv.GetArea;
    
    service Example {
      rpc GetArea(Request) returns (Response) {}
    }
    
    message Request {
    
    }
    
    message Response {
      // 返回错误码
      string ErrNo = 1;
      // 返回错误信息
      string ErrMsg = 2;
      // 返回数据类型
      message Area {
        int32 Aid = 1;
        string Aname = 2;
      }
      // 用自定义类型返回的数组
      repeated Area Data = 3;
    }
    
    $ cd /home/lpgit/go/src/ihome/GetArea
    $ protoc --proto_path=. --go_out=. --micro_out=. proto/getarea/getarea.proto
    

    Web 端

    修改 main.go 文件:添加路由

    // 获取地区信息
    rou.GET("/api/v1.0/areas", handler.GetArea)
    

    handler.go 增加 GetArea 函数

    package handler
    
    import (
    	"context"
    	"encoding/json"
    	"github.com/julienschmidt/httprouter"
    	"github.com/micro/go-grpc"
    	getarea "ihome/GetArea/proto/getarea"
    	"ihome/ihomeWeb/models"
    	"ihome/ihomeWeb/utils"
    	"net/http"
    )
    
    // 获取地区信息
    func GetArea(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    	// 创建新的 gRPC 返回句柄
    	server := grpc.NewService()
    	// 服务初始化
    	server.Init()
    
    	// 创建获取地区的服务并且返回句柄
    	exampleClient := getarea.NewExampleService("go.micro.srv.GetArea", server.Client())
    	// 调用函数并且返回数据
    	rsp, err := exampleClient.GetArea(context.TODO(), &getarea.Request{})
    	if err != nil {
    		return
    	}
    	// 创建返回类型的切片
    	var areas []models.Area
    	// 循环读取服务返回的数据
    	for _, value := range rsp.Data {
    		areas = append(areas, models.Area{Id: int(value.Aid), Name: value.Aname})
    	}
    	// 创建返回数据 map
    	response := map[string]interface{}{
    		"errno":  rsp.ErrNo,
    		"errmsg": rsp.ErrMsg,
    		"data":   areas,
    	}
    	// 注意
    	w.Header().Set("Content-Type", "application/json")
    
    	// 将返回的数据 map 发送给前端
    	if err := json.NewEncoder(w).Encode(response); err != nil {
    		http.Error(w, err.Error(), 503)
    		return
    	}
    }
    

    Server 端

    修改 main.go 内容,之后每次都和下面一样进行修改

    package main
    
    import (
    	"github.com/micro/go-grpc"
    	"github.com/micro/go-log"
    	"github.com/micro/go-micro"
    	"ihome/GetArea/handler"
        // 此处修改
    	getarea "ihome/GetArea/proto/getarea"
    )
    
    func main() {
    	// New Service
        // 此处修改:micro 改为 grpc
    	service := grpc.NewService(
    		micro.Name("go.micro.srv.GetArea"),
    		micro.Version("latest"),
    	)
    
    	// Initialise service
    	service.Init()
    
    	// Register Handler
        // 此处修改 example 改为 getarea
        // handler.Example 改为 handler.Server
    	getarea.RegisterExampleHandler(service.Server(), new(handler.Server))
    
    	// Run service
    	if err := service.Run(); err != nil {
    		log.Fatal(err)
    	}
    }
    

    handlerexample.go 文件

    package handler
    
    import (
    	"context"
    	"encoding/json"
    	"github.com/astaxie/beego/cache"
    	"github.com/astaxie/beego/orm"
    	"ihome/ihomeWeb/models"
    	"ihome/ihomeWeb/utils"
    	"time"
    
    	_ "github.com/astaxie/beego/cache/redis"
    	_ "github.com/garyburd/redigo/redis"
    	_ "github.com/gomodule/redigo/redis"
    	getarea "ihome/GetArea/proto/getarea"
    )
    
    type Server struct{}
    
    func (e *Server) GetArea(ctx context.Context, req *getarea.Request, rsp *getarea.Response) error {
    	// 初始化 错误码
    	rsp.ErrNo = utils.RECODE_OK
    	rsp.ErrMsg = utils.RecodeText(rsp.ErrNo)
    
    	// 1. 从缓存中获取数据
    	// 准备连接 redis 信息
    	redisConf := map[string]string{
    		"key":   utils.G_server_name,
    		"conn":  utils.G_redis_addr + ":" + utils.G_redis_port,
    		"dbNum": utils.G_redis_dbnum,
    	}
    
    	// 将 map 转化为 json
    	redisConfJson, _ := json.Marshal(redisConf)
    	// 创建 redis 句柄
    	bm, err := cache.NewCache("redis", string(redisConfJson))
    	if err != nil {
    		rsp.ErrNo = utils.RECODE_DBERR
    		rsp.ErrMsg = utils.RecodeText(rsp.ErrNo)
    		return nil
    	}
    	// 获取数据
    	areaInfo := bm.Get("areaInfo")
    	if areaInfo != nil {
    		// 缓存中有数据
    		var areas []map[string]interface{}
    		// 将获取到的数据解码
    		json.Unmarshal(areaInfo.([]byte), &areas)
    
    		for _, value := range areas {
    			rsp.Data = append(rsp.Data, &getarea.Response_Area{Aid: int32(value["aid"].(float64)), Aname: value["aname"].(string)})
    		}
    		return nil
    	}
    
    	// 2. 缓存中没有数据从 mysql 中查找数据
    	o := orm.NewOrm()
    	var areas []models.Area
    	num, err := o.QueryTable("Area").All(&areas)
    	if err != nil {
    		rsp.ErrNo = utils.RECODE_DBERR
    		rsp.ErrMsg = utils.RecodeText(rsp.ErrNo)
    		return nil
    	}
    	if num <= 0 {
    		rsp.ErrNo = utils.RECODE_NODATA
    		rsp.ErrMsg = utils.RecodeText(rsp.ErrNo)
    		return nil
    	}
    
    	// 3. 将查找到的数据存到缓存中
    	// 将获取到的数据转化为 json 格式
    	areasJson, _ := json.Marshal(areas)
    	err = bm.Put("areaInfo", areasJson, 3600*time.Second)
    	if err != nil {
    		rsp.ErrNo = utils.RECODE_DBERR
    		rsp.ErrMsg = utils.RecodeText(rsp.ErrNo)
    		return nil
    	}
    
    	// 4. 将查找到的数据 按照 proto 的格式 发送给前端
    	for _, value := range areas {
    		rsp.Data = append(rsp.Data, &getarea.Response_Area{Aid: int32(value.Id), Aname: value.Name})
    	}
    	return nil
    }
    

    李培冠博客

    欢迎访问我的个人网站:

    李培冠博客:lpgit.com

  • 相关阅读:
    yolo_to_onnx ValueError: need more tan 1 value to unpack
    yolo_to_onnx killed
    C++ 实现二维矩阵的加减乘等运算
    Leetcode 1013. Partition Array Into Three Parts With Equal Sum
    Leetcode 1014. Best Sightseeing Pair
    Leetcode 121. Best Time to Buy and Sell Stock
    Leetcode 219. Contains Duplicate II
    Leetcode 890. Find and Replace Pattern
    Leetcode 965. Univalued Binary Tree
    Leetcode 700. Search in a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/lpgit/p/13565458.html
Copyright © 2020-2023  润新知