GO语言多项目开发环境搭建
程序员文章站
2022-06-03 22:46:50
...
1.go的安装
以Mac为例,linux/windows自行查找资料
- 安装go
brew install go
- 配置环境变量.bash_profile
#go env start
export GOROOT=/usr/local/opt/go/libexec
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH:$GOPATH/bin
#go env end
- 变量生效
source ~/.bash_profile
或者
source ~/.zshrc
或者
exec "$SHELL"
或者
重新打开终端窗口
2.包的管理
- 配置%GOPATH
mkdir -p {$GOPATH/src,$GOPATH/pkg,$GOPATH/bin,$GOPATH/src,$GOPATH/src/xxxx.com/alexhu}
- 安装gopm
go get github.com/gpmgo/gopm
3.Demo项目wstest(WebService Test)
Demo项目代码来自:https://www.cnblogs.com/chevin/p/8086999.html
- 建立目录结构
cd $GOPATH/src/xxxx.com/alexhu
mkdir -p {wstest/vendor,wstest/bin,wstest/wssvr,wstest/wsclt}
- 建立源文件
服务端代码
//wssvr/wssvr.go
package main
import (
"fmt"
"golang.org/x/net/websocket"
"net/http"
"os"
"time"
)
//错误处理函数
func checkErr(err error, extra string) bool {
if err != nil {
formatStr := " Err : %s\n";
if extra != "" {
formatStr = extra + formatStr;
}
fmt.Fprintf(os.Stderr, formatStr, err.Error());
return true;
}
return false;
}
func svrConnHandler(conn *websocket.Conn) {
request := make([]byte, 128);
defer conn.Close();
for {
readLen, err := conn.Read(request)
if checkErr(err, "Read") {
break;
}
//socket被关闭了
if readLen == 0 {
fmt.Println("Client connection close!");
break;
} else {
//输出接收到的信息
fmt.Println(string(request[:readLen]))
time.Sleep(time.Second);
//发送
conn.Write([]byte("World !"));
}
request = make([]byte, 128);
}
}
func main() {
http.Handle("/echo", websocket.Handler(svrConnHandler));
err := http.ListenAndServe(":6666", nil);
checkErr(err, "ListenAndServe");
fmt.Println("Func finish.");
}
客户端代码
//wsclt/wsclt.go
package main
import (
"fmt"
"golang.org/x/net/websocket"
"os"
"sync"
)
var gLocker sync.Mutex; //全局锁
var gCondition *sync.Cond; //全局条件变量
var origin = "http://127.0.0.1:6666/"
var url = "ws://127.0.0.1:6666/echo"
//错误处理函数
func checkErr(err error, extra string) bool {
if err != nil {
formatStr := " Err : %s\n";
if extra != "" {
formatStr = extra + formatStr;
}
fmt.Fprintf(os.Stderr, formatStr, err.Error());
return true;
}
return false;
}
//连接处理函数
func clientConnHandler(conn *websocket.Conn) {
gLocker.Lock();
defer gLocker.Unlock();
defer conn.Close();
request := make([]byte, 128);
for {
readLen, err := conn.Read(request)
if checkErr(err, "Read") {
gCondition.Signal();
break;
}
//socket被关闭了
if readLen == 0 {
fmt.Println("Server connection close!");
//条件变量同步通知
gCondition.Signal();
break;
} else {
//输出接收到的信息
fmt.Println(string(request[:readLen]))
//发送
conn.Write([]byte("Hello !"));
}
request = make([]byte, 128);
}
}
func main() {
conn, err := websocket.Dial(url, "", origin);
if checkErr(err, "Dial") {
return;
}
gLocker.Lock();
gCondition = sync.NewCond(&gLocker);
_, err = conn.Write([]byte("Hello !"));
go clientConnHandler(conn);
//主线程阻塞,等待Singal结束
for {
//条件变量同步等待
gCondition.Wait();
break;
}
gLocker.Unlock();
fmt.Println("Client finish.")
}
- 获得依赖包
cd $GOPATH/src/xxxx.com/alexhu/wstest/vendor
gopm get -l golang.org/x/net/websocket #通过gopm -l下载到当前目录
- 建立Makefile文件。强烈建议熟悉基本都makefile写法用法!!
.PHONY: enable-race
enable-race:
$(eval RACE = -race)
.PHONY: build
build: wssvr wsclt
.PHONY: wssvr
wssvr:
go build $(RACE) -o bin/wssvr ./wssvr
.PHONY: wsclt
wsclt:
go build $(RACE) -o bin/wsclt ./wsclt
.PHONY: run
run: build kill
sleep 0.5
./bin/wssvr &
./bin/wsclt
.PHONY: kill
kill:
-killall wsclt
-killall wssvr
.PHONY: clean
clean:
rm bin/*
.PHONY: test
test:
go test $(RACE) ./...
- 执行项目
make run
4.为什么用gopm
1.直接下载golang.org的包,详情见:https://gopm.io 。
2.灵活:gopm -l 包下载在当前目录里面,可以指定版本,避免不同项目冲突。
项目依赖包建议放在:
/Users/john/go/src/xxxx.com/john/wstest/vendor
其中:
- /Users/john/go: 即为$GOPATH
- /src: 约定的go 目录
- /xxxx.com/john/wstest:公司、作者及项目名,参考github.com项目命名
- /wendor:本项目的三方依赖包存放目录