无法弄清楚如何在二进制Web套接字中使用缓冲区

时间:2019-02-04 17:44:47

标签: go

大家! 我正在尝试使用openstack串行控制台运行代码。它是通过Web套接字公开的。而且我有问题。

我找到了gorrilla websocket lib(很棒),并以this example 作为参考

经过一些调整,现在我有了这样的代码:

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程序员,而且我没有办法做到这一点。最后,我只需要使用字符串即可。

1 个答案:

答案 0 :(得分:0)

log软件包将每条日志消息写在单独的行上。如果日志消息不以换行符结尾,则日志包将添加一个换行符。

这些额外的换行符使输出变乱。要修复输出,请使用不向输出添加换行符的函数替换对log.Printf("%s", message)的调用。以下是一些选项:

将消息写到stderr(与默认日志包配置相同的目的地):

os.Stderr.Write(message)

将消息写到stdout(写程序输出的更常规的位置):

os.Stdout.Write(message)