基于 xorm 的服务端框架 XGoServer

作者:林冠宏 / 指尖下的幽灵

掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8

博客:http://www.cnblogs.com/linguanh/

GitHub : https://github.com/af913337456/

腾讯云专栏: https://cloud.tencent.com/developer/user/1148436/activities


开源地址:https://github.com/af913337456/XGoServer

你可以使用它

  • 简单快速搭建自己的服务端
  • 高级模块拓展,例如 jwt,token模块。数据加密传输等

具备的

  • 日志模块,alecthomas/log4go
  • 路由模块,gorilla/mux
  • 硬存储 / 软存储 采用 xorm 框架
  • 多路 gorutine 设计,增加并发性能
  • 服务端通用的输出数据结构的整合,例如 json
如果你想直接输出一条 json 给客户端,这样子
func main()  {
    router := new (mux.Router)
    router.HandleFunc("/",test2).Methods("GET")
    core.HttpListen(router) 
}
func test2(w http.ResponseWriter,r *http.Request)  {
    // 非常简单的例子, 操作放在内部 , 可以使用 request 来获取自己的参数,再直接组织输出
    core.HandlerMapWithOutputJson(w, func() map[string]interface{} {
        m :=  map[string]interface{}{}
        m["msg"] = "blow me a kiss"
        return m
    })
}
// 结果 : {"msg":"blow me a kiss"}
与数据库交互
func test3(w http.ResponseWriter,r *http.Request)  {
    core.HandlerMapWithOutputJson(w, func() map[string]interface{} {
        // 插入一条评论
        item := &model.Comment{
            Id  :util.NewId(),         // 评论 id
            UserId  :"123456",             // 评论人 id
            Name    :"LinGuanHong",        // 评论人名称
            Content :"hello word",         // 评论内容
        }
        affect,_ := core.Engine.Insert(item)  // 执行插入,传入 struct 引用
        m :=  map[string]interface{}{}
        if affect > 0 {
            m["ret"] = "insert success"
            comments := make([]model.Comment, 0)
            core.Engine.Find(&comments)   // select 出来,获取所有评论输出
            m["msg"] = comments
        }else{
            m["ret"] = "insert failed"
        }
        return m
    })
}

输出的结果是:
{
  "msg": [
    {
      "id": "1kubpgh9pprrucy11e456fyytw",
      "UserId": "123456",
      "name": "LinGuanHong",
      "content": "hello word"
    }
  ],
  "ret": "insert success"
}

使用流程

目录如下

---- config
---- core
---- model
---- threeLibs
---- util
---- server.go

1 在 config 放置配置文件

  • 服务端配置 json 文件 -- server.json,
  • 日志配置文件 -- log.json 例如下面的,他们都会在运行程序后会自动解析和读取

2 threeLibs 目录放置了依赖的第三方库,例如 xorm,不需要你再去 go get

3 model 放置数据实体 struct

{
  "Host": "127.0.0.1",
  "Port": ":8884",
  "FilePort":":8885",
  "DbName":"lgh",
  "DbUser":"root",
  "DbPw":"123456",
  "DbPort":"3306"
}
{
  "EnableConsole": true,
  "ConsoleLevel": "DEBUG",
  "EnableFile": true,
  "FileLevel": "INFO",
  "FileFormat": "",
  "FileLocation": ""
}

从一个最基础的例子开始:

func main()  {
    router := new (mux.Router)
    router.HandleFunc("/",test).Methods("GET")
    /** 在下面添加你的路由 */
    /** add your routine func below */ 
    core.HttpListen(router)  // 简单的 http 监听,当然也提供了 https
}
func test(w http.ResponseWriter,r *http.Request)  {
    fmt.Fprintf(w,"======= hello world! =======")
}
// http 监听
func HttpListen(router *mux.Router)  {
    SimpleInit()  // 此处自动初始化 ---------- ①
    url := config.ServerConfig.Host+config.ServerConfig.Port
    util.LogInfo("服务启动于 : "+url)
    err := http.ListenAndServe(url,router)
    if err !=nil {
        util.LogInfo("http error ===> : "+err.Error())
        return
    }
}
// 绑定配置 json 的信息 以及 初始化 xorm mysql数据库引擎
func SimpleInit() bool {
    if config.BindServerConfig() {
        fmt.Println("BindServerConfig ==================> success")
        config.ConfigureLog(&config.LogConfig)
        CreateDefaultMysqlEngine(
            "mysql",
            config.ServerConfig.DbUser,
            config.ServerConfig.DbPw,
            config.ServerConfig.DbName)
        return true
    }else{
        fmt.Println("BindServerConfig ===> failed")
        return false
    }
}

多路 gorutine 设计,增加并发性能

type FinalResult struct {
    Data interface{}
}

type RetChannel chan FinalResult

func HandlerStruct(handle func() interface{}) *interface{} {
    RetChannel := make(RetChannel, 1)
    go func() {
        result := FinalResult{}
        data := handle()
        result.Data = &data
        RetChannel <- result
        close(RetChannel)
    }()
    ret := <-RetChannel
    return ret.Data.(*interface{})
}

func HandlerMap(handle func() map[string]interface{}) *map[string]interface{} {
    RetChannel := make(RetChannel, 1)
    go func() {
        result := FinalResult{}
        data := handle()
        result.Data = &data
        RetChannel <- result
        close(RetChannel)
    }()
    ret := <-RetChannel
    return ret.Data.(*map[string]interface{})
}

func HandlerStructWithOutputJson(w http.ResponseWriter,handle func() interface{})  {
    RetChannel := make(RetChannel, 1)
    go func() {
        result := FinalResult{}
        data := handle()
        result.Data = &data
        RetChannel <- result
        close(RetChannel)
    }()
    ret := <-RetChannel
    mapRet := ret.Data.(*interface{})
    util.RenderJson(w,mapRet)
}

func HandlerMapWithOutputJson(w http.ResponseWriter,handle func() map[string]interface{}){
    RetChannel := make(RetChannel, 1)
    go func() {
        result := FinalResult{}
        data := handle()
        result.Data = &data
        RetChannel <- result
        close(RetChannel)
    }()
    ret := <-RetChannel
    mapRet := ret.Data.(*map[string]interface{})
    util.RenderJson(w,mapRet)
}

就介绍这么多了

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏潇涧技术专栏

Art of Android Development Reading Notes 11

《Android开发艺术探索》读书笔记 (11) 第11章 Android的线程和线程池

562
来自专栏解Bug之路

从linux源码看socket的close

笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。上篇博客讲了socket的阻塞和非阻塞,这篇就开始谈一谈socket的...

2477
来自专栏Danny的专栏

必备的网络常用测试命令(ping命令)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

3352
来自专栏开发与安全

linux网络编程之TCP/IP基础(三):IP数据报格式和IP地址路由

一、IP数据报格式 IP数据报格式如下: ? 注:需要注意的是网络数据包以大端字节序传输,当然头部也得是大端字节序,也就是说: The most signifi...

2897
来自专栏desperate633

设计模式之备忘录模式(Memento模式)引入备忘录模式备忘录模式的实例备忘录模式分析

我们在使用文本编辑器的时候,一般如果不小心误操作了,按ctrl+z就可以恢复之前的状态,撤销(undo)操作。 撤销的操作,实际上有两步,一是要保存之前的状态...

922
来自专栏老安的博客

openstack windows 镜像密码注入的问题

2282
来自专栏Android中高级开发

Android开发之漫漫长途 XIX——HTTP

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索...

1252
来自专栏梦里茶室

【Chromium中文文档】线程

概览 Chromium是一个极其多线程的产品。我们努力让UI尽可能快速响应,这意味着任何阻塞I/O或者其他昂贵操作不能阻塞UI线程。我们的做法是在线程间传递消息...

2906
来自专栏everhad

小知识 安卓线程和ui

多线程环境下的ui修改   开发过程中,经常需要开启新的线程,并且在其它线程中改变ui线程的ui对象的状态。Android设计出于性能考虑,ui对象为非线程安全...

20110
来自专栏林冠宏的技术文章

基于 xorm 的服务端框架 XGoServer

开源地址:https://github.com/af913337456/XGoServer

2121

扫码关注云+社区

领取腾讯云代金券