当前位置:网站首页>使用Go语言构建Web服务器
使用Go语言构建Web服务器
2022-04-23 02:26:00 【田土豆】
先看一个简单的例子,如何通过Go语言搭建一个简易的Web服务,再由浅入深,介绍实现细节
一个简单的Web服务器
package main
import (
"fmt"
"log"
"net/http"
)
func HelloWorld(w http.ResponseWriter, r *http.Request) {
_, err := fmt.Fprintf(w, "Hello World!")
if err != nil {
log.Panic(err)
}
}
func main() {
//设置访问路由,这里是当url中的路径为/hello时,服务器调用HelloWorld函数(可统一称为handler函数)
http.HandleFunc("/hello", HelloWorld)
//web监听的端口是8080
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Panic(err)
}
}
这里web监听的端口是8080,运行一下程序。然后打开浏览器,输入http://127.0.0.1:8080/hello,会得到如下结果
Web服务器的工作原理
1、首先看HandleFunc函数,看注释大概知道HandleFunc就是用来注册handler函数(也可以叫app,对应之前的HelloWorld函数,用来处理用户请求,并返回结果),两个入参,一个pattern(简单理解为url里的路径),一个handler函数
// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
2、DefaultServerMux是一个ServeMux结构体实例,主要就是用来存储pattern和handler之间的对应关系
type ServeMux struct {
mu sync.RWMutex
m map[string]muxEntry
es []muxEntry // slice of entries sorted from longest to shortest.
hosts bool // whether any patterns contain hostnames
}
type muxEntry struct {
h Handler
pattern string
}
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
3、HandleFunc函数调用了ServeMux实现的方法HandleFunc
// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
if handler == nil {
panic("http: nil handler")
}
mux.Handle(pattern, HandlerFunc(handler))
}
注:mux.Handle(pattern, HandlerFunc(handler))这行里的HandlerFunc是一个函数类型,将handler强制类型转换
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)
4、ServeMux实现的Handle方法,主要就是利用字段m(map[string]muxEntry)存储pattern和handler之间的关系,键是pattern,值是handler
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
mux.mu.Lock()
defer mux.mu.Unlock()
if pattern == "" {
panic("http: invalid pattern")
}
if handler == nil {
panic("http: nil handler")
}
if _, exist := mux.m[pattern]; exist {
panic("http: multiple registrations for " + pattern)
}
if mux.m == nil {
mux.m = make(map[string]muxEntry)
}
e := muxEntry{
h: handler, pattern: pattern}
mux.m[pattern] = e
if pattern[len(pattern)-1] == '/' {
mux.es = appendSorted(mux.es, e)
}
if pattern[0] != '/' {
mux.hosts = true
}
}
5、ListenAndServe函数就是监听并响应请求
func ListenAndServe(addr string, handler Handler) error {
server := &Server{
Addr: addr, Handler: handler}
return server.ListenAndServe()
}
入参有两个,一个是监听地址,一个是handler,注意这里的handler是指mux(路由器,用来存储pattern和app之间的关系)。如果handler为nil,说明默认使用DefautServeMux,下面我们也可以自己构造一个mux
package main
import (
"fmt"
"log"
"net/http"
)
func HelloWorld(w http.ResponseWriter, r *http.Request) {
_, err := fmt.Fprintf(w, "Hello World!")
if err != nil {
log.Panic(err)
}
}
func main() {
//自定义一个mux
mux := new(http.ServeMux)
//注册函数
mux.HandleFunc("/hello", HelloWorld)
if err := http.ListenAndServe(":8080", mux); err != nil {
log.Panic(err)
}
}
运行一下程序,然后打开浏览器,输入http://127.0.0.1:8080/hello,同样会得到预期结果
版权声明
本文为[田土豆]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_42216109/article/details/123538893
边栏推荐
- Daily question (April 22, 2022) - rotation function
- If you want to learn SQL with a Mac, you should give yourself a good reason to buy a Mac and listen to your opinions
- Numerical remapping method (remap)
- Multithreading technology core
- Dynamic memory management
- The importance of ERP integration to the improvement of the company's system
- Hyperscan -- 2 compilation
- Kubernetes cluster installation based on Kirin SP10 server version
- Execute external SQL script in MySQL workbench and report error
- Develop a chrome plug-in from 0 (2)
猜你喜欢
Redis memory recycling strategy
006_redis_SortedSet类型
How to call out services in idea and display the startup class in services
[assembly language] understand "stack" from the lowest point of view
Real math problems in 1958 college entrance examination
Usage of vector common interface
VMware virtual machine installation openwrt as side route single arm route img image to vmdk
Lane cross domain problem
每日一题(2022-04-22)——旋转函数
How does Axure set the content of the text box to the current date when the page is loaded
随机推荐
005_redis_set集合
So library dependency
Consider defining a bean of type 'com netflix. discovery. AbstractDiscoveryClientOptionalArgs‘
Campus transfer second-hand market source code
OJ daily practice - Finish
LeetCode 349. Intersection of two arrays (simple, array) Day12
关于局域网浅谈
Go language ⌈ mutex and state coordination ⌋
Realize linear regression with tensorflow (including problems and solutions in the process)
leetcode:27. Remove element [count remove]
New book recommendation - IPv6 technology and application (Ruijie version)
How to call out services in idea and display the startup class in services
2018 China Collegiate Programming Contest - Guilin Site J. stone game
006_ redis_ Sortedset type
012_ Access denied for user ‘root‘@‘localhost‘ (using password: YES)
005_ redis_ Set set
IAR embedded development stm32f103c8t6 Lighting LED
Chinese scientists reveal a new mechanism for breaking through the bottleneck of rice yield
Leetcode46 Full Permutation
006_ redis_ Jedis quick start