编程原创Golang技术交流程序员

Go 100来行代码创建自己的静态服务器

2017-09-01  本文已影响706人  IT锟

Go 它可以在一台计算机上用几秒钟的时间编译一个大型的Go程序,高并发等特性。网上大都是些基础教程,各种语法糖的介绍,我还是更喜欢来个综合示例:

这个示例有以下特点:
除了能访问本地文件,还实时输入访问的日志到控制台,可以实时的看到你服务器的输入输出。
你也还可以在go文件上拓展自己的访问路由单独处理。

先来看下访问的效果吧:

实现后的效果.png

go代码文件


package main

import (
    "encoding/json"
    "html/template"
    "io/ioutil"
    "log"
    "net/http"
    "os"
    "strings"
    "time"
)

var mux map[string]func(http.ResponseWriter, *http.Request)

func main() {

    server := http.Server{
        Addr:        ":8081",
        Handler:     &myHandle{},
        ReadTimeout: 5 * time.Second,
    }
    mux = make(map[string]func(http.ResponseWriter, *http.Request))

    //这里配置路由,可以添加自己的方法去处理对应的路由
    mux["/"] = Index

    log.Println("已为您启动了服务,您可以打开浏览器访问 127.0.0.1:8081 ,我会输入访问日志。")

    err := server.ListenAndServe()
    if err != nil {
        log.Fatal(err)
    }

}

type myHandle struct{}

func (*myHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {

    log.Println("请求url:", r.URL.String())
    log.Println("请求方法:", r.Method)

    //解析,默认不解析的,否者r.Form将拿不到数据
    r.ParseForm()

    log.Println("请求报文:", r)
    log.Println("请求的参数:", r.Form)

    if h, ok := mux[r.URL.String()]; ok {
        h(w, r)
    } else {
        fileTer(w, r)
    }

}

//返回的jsonBean
type BaseJsonBean struct {
    Code    int         `json:"code"`
    Message string      `json:"message"`
    Data    interface{} `json:"data"`
}

//创建jsonBean
func NewBaseJsonBean(code int, message string, data interface{}) *BaseJsonBean {
    return &BaseJsonBean{
        Code:    code,
        Message: message,
        Data:    data,
    }
}

//文件过滤器
func fileTer(w http.ResponseWriter, r *http.Request) {

    path := r.URL.Path
    //判断是否有.
    if strings.Contains(path, ".") {
        request_type := path[strings.LastIndex(path, "."):]
        switch request_type {
        case ".css":
            w.Header().Set("content-type", "text/css; charset=utf-8")
        case ".js":
            w.Header().Set("content-type", "text/javascript; charset=utf-8")
        default:
        }
    }

    wd, err := os.Getwd()
    if err != nil {
        log.Println("获取系统路径失败:", err)
    }

    fin, err := os.Open(wd + path)
    if err != nil {

        log.Println("读取文件失败:", err)
        //关闭文件句柄
        fin.Close()

        //返回json头
        w.Header().Set("content-type", "text/json; charset=utf-8")

        result := NewBaseJsonBean(404, "", "")
        bytes, _ := json.Marshal(result)
        w.Write([]byte(string(bytes)))

        log.Println("返回数据:", string(bytes))

        return
    }

    fd, _ := ioutil.ReadAll(fin)
    w.Write([]byte(fd))

}

//默认访问方法
func Index(w http.ResponseWriter, r *http.Request) {

    t, err := template.ParseFiles("index.html")
    if err != nil {
        log.Println("未找到index.html文件,我为您展示默认的首页 :) 快去创建自己的首页吧")

        w.Header().Set("content-type", "text/html; charset=utf-8")
        w.Write([]byte(indeTpl))

    } else {
        t.Execute(w, nil)
    }

}

//首页模板
var indeTpl = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>It Work</title>
</head>
<body>
<h1>:)</h1>
<h3>It Work</h3>
</body>
</html>
`

代码行数.png

没错,就这么多。抛去换行和注释,也就100来行,这就完成了一个静态的服务器,把他丢到哪个件夹哪个就是服务器访问的地址。

运行起来的访问效果.png 控制台输出效果.png

可能功能上不能和成熟的Apache和Nginx比,但是已基本实现了静态服务器的功能。控制台会实时输出访问的日志,如果觉得不错可以自己扩展,这个程序端口是写死的,你可以改成从配置文件读取。控制台的日志也可以输出到log日志文件等。

现在你只需要
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build HTTPServer.go
编译给64位windows的用户用
go build HTTPServer.go
编译给mac用户用(我开发环境是mac)
具体的编译,可以在网上找更详细的资料,我也里也就抛砖引玉下。

有问题可以留言。

[获取授权]

上一篇下一篇

猜你喜欢

热点阅读