Go websockets 数据 gopherjs

huangapple go评论91阅读模式
英文:

Go websockets data gopherjs

问题

我目前正在尝试使用Websockets进行通信,我的代码如下(我使用gorilla库):

buff := bytes.NewBuffer([]byte{})
binary.Write(buff, binary.LittleEndian, uint64(1))
binary.Write(buff, binary.LittleEndian, len(message))
binary.Write(buff, binary.LittleEndian, message)
client.Write <- buff.Bytes()

c.Write通道位于一个for select循环中:

case msg := <-client.Write:
    buffer := &bytes.Buffer{}
    err := binary.Write(buffer, binary.LittleEndian, msg)
    if err != nil {
        return
    }
    err = client.Ws.WriteMessage(websocket.BinaryMessage, buffer.Bytes())
    if err != nil {
        return
    }
    buffer.Reset()

client只是一个结构体:

type Client struct {
    Ws      *websocket.Conn
    Read    chan []byte
    Write   chan []byte
    Account *models.Account
}

消息成功发送后,我这样读取它:

b, err := conn.Read(buff)
if err != nil {
    utils.Log("Error while reading from socket " + err.Error())
    return
}
buffer := bytes.NewBuffer(buff[:b])
t, err := binary.ReadUvarint(buffer)
utils.Log(t)
if err != nil {
    utils.Log("Error while reading from socket " + err.Error())
    return
}
switch t {
case 1:
    roomsLen, err := binary.ReadUvarint(buffer)
    if err != nil {
        utils.Log("Error while reading rooms len " + err.Error())
        return
    }
    utils.Log(roomsLen)
    roomsBytes := make([]byte, roomsLen)
    binary.Read(buffer, binary.LittleEndian, roomsBytes)
    rooms := []*Room{}
    err = json.Unmarshal(roomsBytes, rooms)
    if err != nil {
        utils.Log("Error while unmarshaling room list " + err.Error())
        return
    }
    utils.Log(rooms)

utils.Log函数只是这样的:

func Log(msg interface{}) {
    n := time.Now()
    console.Call("log", fmt.Sprintf("[%v:%v:%v] %v", n.Hour(), n.Minute(), n.Second(), msg))
}

问题是,第一个uint64是我期待的值(1),但我读取的第二个uint64始终为0,而在记录它时(len(message)),它给出的是52。

由于始终为0,我无法正确地进行解组。

所以我不确定我做错了什么,或者这是否是使用Websockets的正确方式。

英文:

I'm currently trying to communicate using websockets and my code is the following (im using gorilla)

buff := bytes.NewBuffer([]byte{})
binary.Write(buff, binary.LittleEndian, uint64(1))
binary.Write(buff, binary.LittleEndian, len(message))
binary.Write(buff, binary.LittleEndian, message)
client.Write &lt;- buff.Bytes()

The c.Write channel its inside a for select loop

case msg := &lt;-client.Write:
    buffer := &amp;bytes.Buffer{}
	err := binary.Write(buffer, binary.LittleEndian, msg)
	if err != nil {
		return
	}
	err = client.Ws.WriteMessage(websocket.BinaryMessage, buffer.Bytes())
	if err != nil {
		return
	}
	buffer.Reset()

And client is just a struct

type Client struct {
	Ws      *websocket.Conn
	Read    chan []byte
	Write   chan []byte
	Account *models.Account
}

The message is sent successfully and I read it like this

b, err := conn.Read(buff)
if err != nil {
	utils.Log(&quot;Error while reading from socket &quot; + err.Error())
	return
}
buffer := bytes.NewBuffer(buff[:b])
t, err := binary.ReadUvarint(buffer)
utils.Log(t)
if err != nil {
	utils.Log(&quot;Error while reading from socket &quot; + err.Error())
	return
}
switch t {
case 1:
	roomsLen, err := binary.ReadUvarint(buffer)
	if err != nil {
		utils.Log(&quot;Error while reading rooms len &quot; + err.Error())
	    return
	}
	utils.Log(roomsLen)
	roomsBytes := make([]byte, roomsLen)
	binary.Read(buffer, binary.LittleEndian, roomsBytes)
	rooms := []*Room{}
	err = json.Unmarshal(roomsBytes, rooms)
	if err != nil {
		utils.Log(&quot;Error while unmarshaling room list &quot; + err.Error())
		return
	}
	utils.Log(rooms)

The utils.Log function is just this

func Log(msg interface{}) {
	n := time.Now()
	console.Call(&quot;log&quot;, fmt.Sprintf(&quot;[%v:%v:%v] %v&quot;, n.Hour(), n.Minute(),    n.Second(), msg))
}

Thing is the first uint64 is the one im waiting (1) but the second uint64 im reading is always 0 while loggin it (len(message)) gives me 52

And since its always 0 I cant unmarshal it properly

So I'm not sure what I am doing wrong or if this is not a correct way to use websockets.

答案1

得分: 1

小错误。你正在使用"ReadUvarint"读取uint64类型的数据(varint是一种不同类型的数据)。

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
)

func main() {
	b := bytes.NewBuffer([]byte{})
	e1 := binary.Write(b, binary.LittleEndian, uint64(10))
	e2 := binary.Write(b, binary.LittleEndian, uint64(20))
	
	fmt.Println("写入 10 和 20:", e1, e2)

	{
		r := bytes.NewBuffer(b.Bytes())
		res, e := binary.ReadUvarint(r)
		res2, e2 := binary.ReadUvarint(r)
		fmt.Println("在这里使用 ReadUvarint:", res, res2, e, e2, b.Bytes())
	}
	{
		r := bytes.NewBuffer(b.Bytes())
		var res, res2 uint64
		e := binary.Read(r, binary.LittleEndian, &res)
		e2 := binary.Read(r, binary.LittleEndian, &res2)
		fmt.Println("在这里使用读取到 uint64 的 Read:", res, res2, e, e2, b.Bytes())
	}
}
英文:

Small error. You're writing uint64 but using "ReadUvarint" to read it (a varint is a different type of data).

package main

import (
	&quot;bytes&quot;
	&quot;encoding/binary&quot;
	&quot;fmt&quot;
)

func main() {
	b := bytes.NewBuffer([]byte{})
	e1 := binary.Write(b, binary.LittleEndian, uint64(10))
	e2 := binary.Write(b, binary.LittleEndian, uint64(20))
	
	fmt.Println(&quot;writing 10 and 20&quot;, e1, e2)

	{
		r := bytes.NewBuffer(b.Bytes())
		res, e := binary.ReadUvarint(r)
		res2, e2 := binary.ReadUvarint(r)
		fmt.Println(&quot;using readuvarint here        :&quot;, res, res2, e, e2, b.Bytes())
	}
	{
		r := bytes.NewBuffer(b.Bytes())
		var res, res2 uint64
		e := binary.Read(r, binary.LittleEndian, &amp;res)
		e2 := binary.Read(r, binary.LittleEndian, &amp;res2)
		fmt.Println(&quot;using read into uint64&#39;s here :&quot;, res, res2, e, e2, b.Bytes())
	}
}

huangapple
  • 本文由 发表于 2016年4月26日 06:10:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/36852000.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定