go - 无法弄清楚如何将缓冲区与二进制 Web 套接字一起使用
问题描述
每个人!我正在尝试让我的 go 代码与 openstack 串行控制台一起工作。它通过网络套接字公开。我有问题。
我找到了 gorrilla websocket lib(这很棒)并将这个例子作为参考
通过一些调整,现在我有了这样的代码:
package main
import (
"log"
"net/url"
"os"
"os/signal"
"time"
"net/http"
"github.com/gorilla/websocket"
)
func main() {
DialSettings := &websocket.Dialer {
Proxy: http.ProxyFromEnvironment,
HandshakeTimeout: 45 * time.Second,
Subprotocols: []string{"binary",},
ReadBufferSize: 4096,
WriteBufferSize: 4096,
}
log.SetFlags(0)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
u, _ := url.Parse("ws://172.17.0.64:6083/?token=d1763f2b-3466-424c-aece-6aeea2a733d5") //websocket url as it outputs from 'nova get-serial-console test' cmd
log.Printf("connecting to %s", u.String())
c, _, err := DialSettings.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
log.Printf("%s", message)
}
}()
c.WriteMessage(websocket.TextMessage, []byte("\n")) //just to force output to console
for {
select {
case <-done:
return
case <-interrupt:
log.Println("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}
我得到这样的输出:
connecting to ws://172.17.0.64:6083/?token=d1763f2b-3466-424c-aece-6aeea2a733d5
CentOS Linux 7
(C
ore)
K
erne
l
3.10.0-862.el7.x86_64
o
n an
x
86_64
centos
-test login:
一团糟……
我认为这是因为我只收到一大块字节而无法分隔它们。我需要一些缓冲区来存储它们以及何时执行类似bufio.ReadLine
. 但我不是最有经验的 Go 程序员,我没有办法做到这一点。最后,我只需要使用字符串即可。
解决方案
日志包将每条日志消息写在单独的行上。如果日志消息不以换行符结尾,则日志包将添加一个。
这些额外的换行符正在混淆输出。要修复输出,请将调用替换为log.Printf("%s", message)
不向输出添加换行符的函数。以下是一些选项:
将消息写入标准错误(与默认日志包配置相同的目的地):
os.Stderr.Write(message)
将消息写入标准输出(写入程序输出的更常规位置):
os.Stdout.Write(message)
推荐阅读
- c# - 如何使用 .net 的 awssdk 通过 lambda 函数将数据添加到 kenisis firehose?
- reactjs - 如何在反应中映射选框标记内的元素数组
- symfony - Symfony set base route for all controllers that extend a certain controller
- wordpress - 如何将结帐页面中的电话字段更改为必填项
- databricks - 以编程方式将库导入 Databricks 中的工作区
- azure - 为什么 VScode pwsh 终端无法看到我的 azure 资源组?
- php - 致命错误:找不到类“Extendware_EWCore_Model_Autoload”
- javascript - 函数在节点 js 中没有返回正确的值
- python - 字节对象中的双引号与烧瓶响应数据中的双引号
- javascript - 如何获取命令“L.control.layers”的单选按钮的信息?