- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在实现一个服务器来流式传输许多 float 数组。我需要一些帮助来设计我的系统以实现以下目标:
如有任何回复,我们将不胜感激。这是我目前的想法:
package main
import (
"fmt"
"io"
"net/http"
"strconv"
"time"
)
func main() {
c := AudioProcess()
handleHello := makeHello(c)
http.HandleFunc("/", handleHello)
http.ListenAndServe(":8000", nil)
}
func makeHello(c chan string) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
for item := range c { // this loop runs when channel c is closed
io.WriteString(w, item)
}
}
}
func AudioProcess() chan string {
c := make(chan string)
go func() {
for i := 0; i <= 10; i++ { // Iterate the audio file
c <- strconv.Itoa(i) // have my frame of samples, send to channel c
time.Sleep(time.Second)
fmt.Println("send ", i) // logging
}
close(c) // done processing, close channel c
}()
return c
}
最佳答案
我不完全确定这是否能解决您的问题,因为我不完全了解您的用例,但尽管如此,我还是提出了以下解决方案。
我将 Gin 用于 HTTP 路由器,因为它对我来说更舒服,但我很确定您可以调整代码以适合您的代码。我做的很匆忙(抱歉),所以可能存在我不知道的问题,但如果有任何问题请告诉我。
简而言之:
Manager
照顾几个Client
.它还包含一个 sync.Mutex
确保只有一个线程正在修改 clients
在任何给定时间;InitBackgroundTask()
这将生成一个随机的 float64
号码,并将其传递给所有 clients
在Manager
(如果有的话)。如果没有 clients
,我们只是 sleep ,然后继续......<-c.Writer.CloseNotify()
断开连接时会自动删除 channel (因为该方法返回从而调用 defer
)。我们也可以收到随机float64
下一个后台任务中的编号打勾。最后,如果我们在 20 秒内没有收到任何东西,我们也可以终止。我在这里对您的需求做了几个假设(例如,后台任务将每 Y 分钟返回 X)。如果您正在寻找更精细的流式传输,我建议您改用 websockets(下面的模式仍然可以使用)。
如果您有任何问题,请告诉我。
代码:
package main
import (
"github.com/gin-gonic/gin"
"github.com/satori/go.uuid"
"log"
"math/rand"
"net/http"
"sync"
"time"
)
type Client struct {
uuid string
out chan float64
}
type Manager struct {
clients map[string]*Client
mutex sync.Mutex
}
func NewManager() *Manager {
m := new(Manager)
m.clients = make(map[string]*Client)
return m
}
func (m *Manager) AddClient(c *Client) {
m.mutex.Lock()
defer m.mutex.Unlock()
log.Printf("add client: %s\n", c.uuid)
m.clients[c.uuid] = c
}
func (m *Manager) DeleteClient(id string) {
m.mutex.Lock()
defer m.mutex.Unlock()
// log.Println("delete client: %s", c.uuid)
delete(m.clients, id)
}
func (m *Manager) InitBackgroundTask() {
for {
f64 := rand.Float64()
log.Printf("active clients: %d\n", len(m.clients))
for _, c := range m.clients {
c.out <- f64
}
log.Printf("sent output (%+v), sleeping for 10s...\n", f64)
time.Sleep(time.Second * 10)
}
}
func main() {
r := gin.Default()
m := NewManager()
go m.InitBackgroundTask()
r.GET("/", func(c *gin.Context) {
cl := new(Client)
cl.uuid = uuid.NewV4().String()
cl.out = make(chan float64)
defer m.DeleteClient(cl.uuid)
m.AddClient(cl)
select {
case <-c.Writer.CloseNotify():
log.Printf("%s : disconnected\n", cl.uuid)
case out := <-cl.out:
log.Printf("%s : received %+v\n", out)
c.JSON(http.StatusOK, gin.H{
"output": out,
})
case <-time.After(time.Second * 20):
log.Println("timed out")
}
})
r.Run()
}
注意:如果您在 Chrome 上测试它,您可能必须在 URL 的末尾附加一个随机参数,以便实际发出请求,例如?rand=001
, ?rand=002
等等。
关于go - 如何使用 channel 和 goroutines 构建 Go Web 服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36457512/
我正在使用 go 图表库 https://github.com/wcharczuk/go-chart制作条形图。我面临的问题是标签值很长,我想将文本旋转 45 度以显示完整文本 我喜欢显示的日期格式是
我在构建一个非常简单的通过 cgo 调用 c 代码的 go 程序时遇到了问题。我的设置: $: echo $GOPATH /go $: pwd /go/src/main $: ls ctest.c
没有 C 的背景,只有 Go 的“初学者”经验,我正在尝试弄清楚 main.go 是实际需要的还是只是一个约定。 我想创建一个简单的网络 API,但有人可以为我澄清一下吗? 最佳答案 main.go
我read从 Go 1.4 开始,Go 运行时是用 Go 本身编写的(而不是用 C)。 这怎么可能?如果 Go 程序在运行时之上运行,并且运行时是 Go 程序,那么运行时是否在自身之上运行? 最佳答案
这是“Go 之旅”中的代码示例 Range and Close : package main import ( "fmt" ) func fibonacci(n int, c chan int
给定以下 go.mod 文件: module foo go 1.12 require ( github.com/bar/baz v1.0.0 github.com/rat/cat v1
我有一个 CI/CD 管道,它需要跨平台并与几个不同的管理程序一起工作。为了不必更改 Windows 和 Linux 的构建任务,我认为 Go 将是编写一次代码并在任何地方运行的好方法。然而,考虑到
我有一个 Dockerfile,用于使用 go build 编译 Go 应用程序。我进行了研究,确实建议将 go build 用于生产。 但是我找不到正确的答案来解释为什么。 我了解 go run 创
我尝试在命令提示符#Go lang 中运行该程序-但是当我键入运行“go run hello.go”命令时,我开始了 CreateFile hello.go:The system cannot fin
我正在使用“Go 编程语言”一书学习 Go。第一章介绍os.Open用于读取文件的模块。我尝试打开如下所示的 go 文件。 f, err = os.Open("helloworld.go") 我收
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题?通过 editing this post 添加详细信息并澄清问题. 2年前关闭。 Improve this
为了解决我对 goroutine 的一些误解,我去了 Go 操场跑了 this code : package main import ( "fmt" ) func other(done cha
这个问题在这里已经有了答案: Evaluate/Execute Golang code/expressions like js' eval() (5 个回答) 1年前关闭。 对于任何 go 程序,我想
这是我基本上试图从路径打印基准的代码。 这意味着,如果用户输入“/some/random/path.java”,则输出将为“path”。同样,如果用户arg为“/another/myapp.c”,则输
$ go version 1.13.3 我的文件夹结构如下: GOPATH +---src +--- my-api-server +--- my-auth-server
这个问题在这里已经有了答案: How to embed file for later parsing execution use (4 个答案) What's the best way to bun
我觉得这有点奇怪,为什么这段代码不起作用? package main import "fmt" func main() { var i, j int = 1, 2 k
go编译器执行完如下命令后的可执行文件存放在哪里? $> go run file.go 最佳答案 在 /tmp 文件夹中,如果您使用的是 unix 机器。 如果您使用的是 Windows,则在 \Us
我目前正在开始使用 Go,并且已经深入研究了有关包命名和工作区文件夹结构的注意事项。 不过,我不太确定如何根据 Go 范式正确组织我的代码。 这是我当前的结构示例,它位于 $GOPATH/src 中:
假设我有一个接受用户输入的 Lua 程序,而该输入恰好是有效的 Lua 源代码。这是在程序仍在运行时进行清理、编译和执行的。 Go 是否(或将)实现这样的事情? 最佳答案 我认为以下两个项目之间有足够
我是一名优秀的程序员,十分优秀!