我只是不能让这个NotFoundHandler工作.我想在每个get请求上提供一个静态文件,只要它存在,否则请提供index.html.这是我目前简化的路由器:
func fooHandler() http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Foo"))
}
return http.HandlerFunc(fn)
}
func notFound(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "public/index.html")
}
func main() {
router = mux.NewRouter()
fs := http.FileServer(http.Dir("public"))
router.Handle("/foo", fooHandler())
router.PathPrefix("/").Handler(fs)
router.NotFoundHandler = http.HandlerFunc(notFound)
http.ListenAndServe(":3000", router)
}
Run Code Online (Sandbox Code Playgroud)
/ foo工作正常
/ file-that-exists工作正常
/ file-that-doesnt-exist 不起作用 - 我找不到404页面而不是index.html
那么我在这里做错了什么?
我想创建全局错误处理程序以通过电子邮件发送它.
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
)
func main() {
rtr := mux.NewRouter()
rtr.HandleFunc("/", withPanic).Methods("GET")
http.Handle("/", rtr)
log.Println("Listening...")
http.ListenAndServe(":3001", http.DefaultServeMux)
}
func withPanic(w http.ResponseWriter, r *http.Request) {
panic("somewhere here will be panic, but I don't know where exactly")
}
Run Code Online (Sandbox Code Playgroud)
如何使其全球化.如果我知道错误发生在哪里会很容易
if err != nil {
sendMeMail(err)
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我不确切知道错误发生在哪里,该怎么办?所以我应该添加一个全局的recoverish处理程序.但是如何做到这一点我完全不知道.
我添加defer recover到开头main但它从不执行请求http://localhost:3001.因此不会通过电子邮件发送恐慌.
package main
import (
"errors"
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
func main() {
defer func() {
if r := …Run Code Online (Sandbox Code Playgroud) 我正在使用Go(Golang)1.4.2和一个nginx 1.4.6反向代理后面的Gorilla WebSockets.大约一分钟打开页面后,我的WebSockets正在断开连接.Chrome和Firefox上也出现相同的行为.
起初,我在使用WebSockets连接服务器和客户端时遇到了问题.然后,我读到我需要调整我的nginx配置.这就是我所拥有的.
server {
listen 80;
server_name example.com;
proxy_pass_header Server;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:1234;
}
}
Run Code Online (Sandbox Code Playgroud)
我的Go代码基本上回应了客户端的消息.(为简洁起见省略了错误).这是我的HandleFunc.
var up = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
ws, _ := up.Upgrade(resp, req, nil)
defer ws.Close()
var s struct {
Foo string
Bar string
}
for {
ws.ReadJSON(&s)
ws.WriteJSON(s)
}
Run Code Online (Sandbox Code Playgroud)
JavaScript也非常简单.
var ws = new WebSocket("ws://example.com/ws/");
ws.addEventListener("message", function(evnt) {
console.log(JSON.parse(evnt.data)); …Run Code Online (Sandbox Code Playgroud) 我正在使用Gorilla mux和net/http包创建一些路由,如下所示
package routes
//some imports
//some stuff
func AddQuestionRoutes(r *mux.Router) {
s := r.PathPrefix("/questions").Subrouter()
s.HandleFunc("/{question_id}/{question_type}", getQuestion).Methods("GET")
s.HandleFunc("/", postQuestion).Methods("POST")
s.HandleFunc("/", putQuestion).Methods("PUT")
s.HandleFunc("/{question_id}", deleteQuestion).Methods("DELETE")
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试编写测试来测试这些路线.例如,我试图测试GET路由专门尝试400返回,所以我有以下测试代码.
package routes
//some imports
var m *mux.Router
var req *http.Request
var err error
var respRec *httptest.ResponseRecorder
func init() {
//mux router with added question routes
m = mux.NewRouter()
AddQuestionRoutes(m)
//The response recorder used to record HTTP responses
respRec = httptest.NewRecorder()
}
func TestGet400(t *testing.T) {
//Testing get of non existent question …Run Code Online (Sandbox Code Playgroud) 我正在使用Gorilla Mux编写REST API,我在组织路由时遇到问题,目前我的所有路由都在这样的main.go文件中定义
//main.go
package main
import (
"NovAPI/routes"
"fmt"
"github.com/gorilla/mux"
"net/http"
)
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/hello", func(res http.ResponseWriter, req *http.Request) {
fmt.Fprintln(res, "Hello")
})
router.HandleFunc("/user", func(res http.ResponseWriter, req *http.Request) {
fmt.Fprintln(res, "User")
})
router.HandleFunc("/route2", func(res http.ResponseWriter, req *http.Request) {
fmt.Fprintln(res, "Route2")
})
router.HandleFunc("/route3", func(res http.ResponseWriter, req *http.Request) {
fmt.Fprintln(res, "Route3")
})
// route declarations continue like this
http.ListenAndServe(":1128", router)
}
Run Code Online (Sandbox Code Playgroud)
所以我想要做的是取出并将这个路由声明拆分成多个文件,我将如何去做呢?提前致谢.
所以我刚开始学习Go编程语言,并花了几个小时来查看示例,引用等等.大多数人都同意,没有比学习语言更好的方法而不是潜入并做出某些东西,这正是我此刻想要做的事情.我正在构建一个Restful Web服务.我已经设法运行基础知识以及插入数据库,注册路由等.但是在过去的两天里,我一直在努力实现应用程序配置/属性.可能只是因为我是新手,我的Go项目架构都是错误的,因此为什么我遇到这样的困难.没有进一步的到期,这是我的项目结构
src
server
database
dbaccess.go
dbcomm.go
handling
handler.go
handlercomm.go
models
config.go
response.go
user.go
routing
routes.go
main.go
Run Code Online (Sandbox Code Playgroud)
这是我的config.go
package models
import (
"io/ioutil"
"encoding/json"
)
type Config struct {
Db map[string]string `json:"db"`
Server map[string]string `json:"server"`
}
func NewConfig(fname string) *Config{
data,err := ioutil.ReadFile(fname)
if err != nil{
panic(err)
}
config := Config{}
err = json.Unmarshal(data,&config)
if err != nil {
panic(err)
}
return config
Run Code Online (Sandbox Code Playgroud)
这是我的主要
func main(){
args := os.Args[1:]
if len(args) == 0{
fmt.Println("********************\nMust specify a config file in …Run Code Online (Sandbox Code Playgroud) 我一直在研究Go项目,其中使用gorilla/mux作为路由器.
我需要能够拥有与路由关联的查询值,但这些值应该是可选的.这意味着我想要捕获两者/articles/123并/articles/123?key=456在同一个处理程序中.
为了做到这一点,我尝试使用r.Queries接受键/值对的方法:路由器.
Path("/articles/{id:[0-9]+}").Queries("key", "{[0-9]*?}")
Run Code Online (Sandbox Code Playgroud)
但这只使value(456)可选,但不是key.因此,无论/articles/123?key=456和/articles/123?key=是有效的,但不是/articles/123.
编辑:另一个要求是,在注册路由后,我想以编程方式构建它们,r.Queries即使文档特别指出它是可能的,我似乎无法弄清楚如何使用(https://github.com/gorilla/mux #registered-urls).
@jmaloney回答有效,但不允许从名称构建URL.
在 Go 中,我尝试了简单的数据库连接。我需要导入gorilla/mux,但我不能。
我正在使用 VS 代码。cd进入我的项目目录后,我创建main.go并运行了
go get -u github.com/gorilla/mux
这是main.go
package main
import (
"database/sql"
"fmt"
"github.com/gorilla/mux"
_ "github.com/lib/pq"
)
const (
host = "localhost"
port = 3000
user = "postgres"
password = "postgres"
dbname = "test1"
)
func main() {
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
db, err := sql.Open("postgres", psqlInfo)
if err != nil {
panic(err)
}
defer db.Close()
err = db.Ping() …Run Code Online (Sandbox Code Playgroud) 我是Go的新手,并且无法找到任何关于此的信息,也许此时此刻不可能.
我试图删除或替换多路复用路由(使用http.NewServeMux或gorilla的mux.Router).我的最终目标是能够启用/禁用路由或路由集,而无需重新启动程序.
我可以在处理程序基础上完成此操作,如果该功能被"禁用",则返回404,但我宁愿找到更通用的方法来执行此操作,因为我想为我的应用程序中的每个路由实现它.
或者我会更好地跟踪禁用的url模式并使用一些中间件来阻止处理程序执行?
如果有人能够至少指出我正确的方向,我绝对会发布解决方案的代码示例,假设有一个.谢谢!
我对 Go 非常陌生,并且发现自己将套接字作为我的第一个项目。这是一个多余的问题,但我无法理解如何将 websocket 更新发送到 Go 中的特定客户端(使用 Gorilla)。
我试图解决的广泛问题是 - 使用 websockets 和 ES/Lucene 之类的搜索引擎构建预先输入。我在我的搜索引擎上维护了一堆索引,并在它周围有一个 Go 包装器。当我开始在 Go 中使用 websockets 时,我找到了几乎所有显示广播机制的示例。当我尝试深入研究并尝试根据此线程和此答案中给出的示例修改 Gorilla 的 github 存储库中给出的示例时,我似乎不明白它是如何适应的connectionsclient.go
理想情况下,我希望看到这种工作的方式是 -
服务器如何唯一标识Client?
我使用了 Gorilla's Github repo上给出的例子
从我的代码库中hub.go有以下内容
type Hub struct {
// Registered clients.
clients map[*Client]bool
// Inbound messages from the clients.
broadcast chan []byte
// Register requests from the clients.
register chan *Client
// Unregister requests …Run Code Online (Sandbox Code Playgroud)