我正在尝试用 Go 学习 websocket。我一直在研究 gorilla websocket 的示例。
我已经查看了这两个示例,展示了如何使用 gorilla websocket:
https://github.com/gorilla/websocket/tree/master/examples
https://www.youtube.com/watch?v=ysAZ_oqPOo0
所有这些示例都展示了如何连接到 websocket 服务器、发送和接收文本。但我不明白的是你如何可以只发送给一个客户。因为在现实世界的应用程序中,您将拥有用户,并且我们不希望所有用户都收到相同的消息和相同的数据。有没有办法让我获得连接的唯一 ID,我可以将其保存在像 Redis 这样的数据库中,并将其链接到同一数据库中的用户 ID,然后使用该 Websocket ID 发送回特定客户端(如果可以)用户 ID 收到消息或通知?这是一个人会如何去做并实现这样的事情吗?如果是这样的话,我该怎么办?
如果我在结构中有这样的嵌套映射变量:
type someStruct struct {
nestedMap map[int]map[string]string
}
var ss = someStruct {
nestedMap: make(map[int]map[string]string),
}
Run Code Online (Sandbox Code Playgroud)
这不起作用并且会出现运行时错误。
我如何初始化它?
我在用
$location.path('/login');
Run Code Online (Sandbox Code Playgroud)
如果用户未登录,则重定向回登录页面,或者通常使用此方法在任何地方重定向.但是,如果我已经有一个看起来像这样的网址
/register/final-step?token=mF6xY2cQvB9Vccb0J1l5uTu4H10lWkkf
并重定向到
$location.path('/');
那么搜索参数不会被清除,所以我得到这样的网址
/?token=mF6xY2cQvB9Vccb0J1l5uTu4H10lWkkf
即使我使用UI-Router
$state.go('home');
Run Code Online (Sandbox Code Playgroud)
该
?token=mF6xY2cQvB9Vccb0J1l5uTu4H10lWkkf
部分仍在那里.
我不明白.每次我需要去另一个州或网址时,我是否真的需要手动清除参数?这对我来说似乎不合法.我做错了什么?我不想这样做,window.location.href
因为这会使整页重新加载,这不是我想要做的事情.
我该怎么做才能清除参数?我一定做错了什么.
在Gorilla websocket的示例目录中,有一个名为hub.go的文件.
https://github.com/gorilla/websocket/blob/master/examples/chat/hub.go
在这里,您可以在类型集线器上找到执行此操作的方法.
func (h *hub) run() {
for {
select {
case c := <-h.register:
h.connections[c] = true
case c := <-h.unregister:
if _, ok := h.connections[c]; ok {
delete(h.connections, c)
close(c.send)
}
case m := <-h.broadcast:
for c := range h.connections {
select {
case c.send <- m:
default:
close(c.send)
delete(h.connections, c)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么它不仅仅是像这样在最后一个案例中直接发送到c.send频道?
case m := <-h.broadcast:
for c := range h.connections {
c.send <- m
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试为静态文件创建一个非常简单的gzip中间件.但是我next.ServeHTTP(w, r)
在代码中调用了5个不同的位置,如果我推迟这个会发生什么?在运行返回的函数之前是否会调用它?
这就是我所拥有的:
func gzipHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
// If for some weird reason client does not understand gzip, then continue.
next.ServeHTTP(w, r)
return
}
path := filepath.FromSlash(filepath.Join(cfg.PublicHTML, r.URL.Path))
if _, err := os.Stat(path); os.IsNotExist(err) {
// If file or folder does not exists, then continue.
next.ServeHTTP(w, r)
return
}
var ext string
for _, v := range cfg.GzipExt {
if strings.HasSuffix(r.URL.Path, v) {
ext = v
} …
Run Code Online (Sandbox Code Playgroud) 我有一个包含UIStackView的UIScrollView,并且向其中添加了视图,并且如果UIStackView需要的空间比屏幕大,那么它会滚动,这要归功于UIScrollView。
我能够在视图上设置恒定的高度,但是我还需要在它们上设置特定的宽度,以便它们具有特定的宽度,并且也位于堆栈视图的中心。
像这样的事情,除了widthAnchor不起作用。
import UIKit
class ViewController: UIViewController {
let scrollView: UIScrollView = {
let sv = UIScrollView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.backgroundColor = .gray
return sv
}()
let stackView: UIStackView = {
let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.axis = .vertical
return sv
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
scrollView.addSubview(stackView)
stackView.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true
stackView.rightAnchor.constraint(equalTo: scrollView.rightAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true …
Run Code Online (Sandbox Code Playgroud) 我只是试图形成数据,我不太明白使用哪种方法.
在本文中:http://astaxie.gitbooks.io/build-web-application-with-golang/content/en/04.1.html
他们r.ParseForm()
通过这样做来使用和获取帖子值r.Form["username"]
.
但是当我在我自己的代码中尝试这个时它没有用,我反而得到了一些字符串,所以我必须这样做r.Form["username"][0]
才能获得字符串值.
为什么与文章中显示的不同?为什么我会得到一些字符串?
还有另一种可以像这样使用的方法r.FormValue("username")
.
还有一个r.PostFormValue("username")
,另一个!
你应该在不同的情况下使用哪一个?
我有一些我希望循环多次的整数,但每次我做另一个循环时,我想从父循环中排除该项.
像这样的东西:
func main() {
as := []int{0, 1, 2, 3}
for i, a := range as {
bs := make([]int, len(as))
copy(bs, as)
bs = append(bs[:i], bs[i+1:]...)
for i, b := range bs {
cs := make([]int, len(bs))
copy(cs, bs)
cs = append(cs[:i], cs[i+1:]...)
for i, c := range cs {
ds := make([]int, len(cs))
copy(ds, cs)
ds = append(ds[:i], ds[i+1:]...)
for _, d := range ds {
fmt.Println(a, b, c, d)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
此代码的输出是:
0123 …
Run Code Online (Sandbox Code Playgroud) 我试图了解当添加更多内核时go服务器如何扩展,但似乎我看不到改进,我不知道为什么.
增加核心时,似乎没有任何变化.我是否需要在代码中执行某些操作才能让它知道我想要使用多个核心?这对性能有帮助吗?
我用于测试的代码是一个输出"Hello World"的简单服务器.
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Hello World"))
})
http.ListenAndServe(":80", nil)
}
Run Code Online (Sandbox Code Playgroud)
我正在对virtualbox进行测试.
这些结果有1个核心:
$ nproc
1
Run Code Online (Sandbox Code Playgroud)
使用1核心的ab进行测试:
$ ab -n 10000 -c 1000 http://127.0.0.1/
Run Code Online (Sandbox Code Playgroud)
来自ab的结果为1核心:
Concurrency Level: 1000
Time taken for tests: 1.467 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1280000 bytes
HTML transferred: 110000 bytes
Requests per second: 6815.42 [#/sec] (mean)
Time per request: 146.726 [ms] (mean)
Time per request: …
Run Code Online (Sandbox Code Playgroud) 怎么这样简单的东西不起作用?
c1 := make(chan string)
c1 <- "foo"
fmt.Println(<-c1)
Run Code Online (Sandbox Code Playgroud)
但如果我把它放在一个常规程序中它有效吗?
c1 := make(chan string)
go func() {
c1 <- "foo"
}()
fmt.Println(<-c1)
Run Code Online (Sandbox Code Playgroud)
这个问题可能看似简单而愚蠢,但我试图理解为什么我不能这样做,在这种情况下我不知道有什么更好的问题.