欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

其中:

  1. /Users/john/go: 即为$GOPATH
  2. /src: 约定的go 目录
  3. /xxxx.com/john/wstest:公司、作者及项目名,参考github.com项目命名
  4. /wendor:本项目的三方依赖包存放目录