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


    流程

    获取地域信息流程

    接口

    # 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

  • 相关阅读:
    MATLAB数据处理快速学习教程
    dev -c++ 快捷键
    SQL 通配符
    如何利用SQL语句求日期的时间差值,并汇总网上的一些信息
    matlab使用常犯的错误
    matlab中将矩阵按照行打乱顺序的一个例子
    我所认识的PCA算法的princomp函数与经历 (基于matlab)
    java 读取本地的json文件
    Oracle数据库——SQL基本查询
    Oracle数据库——表的创建与管理
  • 原文地址:https://www.cnblogs.com/lpgit/p/13565458.html
Copyright © 2020-2023  润新知