[BUG]Binary data contains ";" will be droped!
StartAt24 opened this issue · comments
Sorry to bother you. But i have found the bug.
It is in neffos.js
.
I'm using protobuf
with neffos.js
. The data that protobuf make
counld contain ;
. So that my message will be drop in neffos.js
in here.
var isArrayBuffer = data instanceof ArrayBuffer;
var dts;
console.log(isArrayBuffer)
if (isArrayBuffer) {
var arr = new Uint8Array(data);
var sepCount = 1;
var lastSepIndex = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] == messageSeparatorCharCode) { // sep char.
sepCount++;
lastSepIndex = i;
}
}
// Drop here!!!!!!!!!!!!
if (sepCount != validMessageSepCount) {
msg.isInvalid = true;
console.log("return at validMessageSepCount")
return msg;
}
dts = splitN(textDecoder.decode(arr.slice(0, lastSepIndex)), messageSeparator, validMessageSepCount - 2);
dts.push(data.slice(lastSepIndex + 1, data.length));
msg.SetBinary = true;
}
else {
dts = splitN(data, messageSeparator, validMessageSepCount - 1);
}
I thank it is a bug. Cannot just split message by ;
.
Here is the reproducible code.
Server
package main
import (
"github.com/kataras/iris"
"fmt"
"github.com/kataras/iris/websocket"
"github.com/kataras/neffos"
"time"
)
// 全局变量
var page = struct {
Title string
}{"Collector"}
func main(){
app := iris.New()
ws_server := startWebSocketServer(app)
go pub_thread(ws_server)
app.RegisterView(iris.HTML("./static", ".html"))
app.Get("/" ,func(ctx iris.Context){
ctx.ViewData("Page", page)
ctx.View("index.html")
})
app.HandleDir("/", "./static")
app.Run(iris.Addr(":5000"), iris.WithoutPathCorrection)
}
var serverEvents = websocket.Namespaces{
"default": websocket.Events{
websocket.OnNamespaceConnected: func(nsConn *websocket.NSConn, msg websocket.Message) error {
// with `websocket.GetContext` you can retrieve the Iris' `Context`.
ctx := websocket.GetContext(nsConn.Conn)
fmt.Printf("[%s] connected to namespace [%s] with IP [%s]\n",
nsConn, msg.Namespace,
ctx.RemoteAddr())
return nil
},
websocket.OnNamespaceDisconnect: func(nsConn *websocket.NSConn, msg websocket.Message) error {
fmt.Printf("[%s] disconnected from namespace [%s]\n", nsConn, msg.Namespace)
return nil
},
"stream": func(nsConn *websocket.NSConn, msg websocket.Message) error {
// room.String() returns -> NSConn.String() returns -> Conn.String() returns -> Conn.ID()
fmt.Printf("[%s] sent: %s", nsConn, string(msg.Body))
// Write message back to the client message owner with:
// nsConn.Emit("chat", msg)
// Write message to all except this client with:
nsConn.Conn.Server().Broadcast(nsConn, msg)
return nil
},
},
}
func startWebSocketServer(app *iris.Application) *neffos.Server{
server := websocket.New(websocket.DefaultGorillaUpgrader, serverEvents)
server.OnConnect = func(c *websocket.Conn) error {
fmt.Printf("[%s] connected to the server.\n", c)
return nil
}
server.OnDisconnect = func(c *websocket.Conn){
fmt.Printf("[%s] disconnected from the server.", c)
}
fmt.Printf("Listening on: %d\nPress CTRL/CMD+C to interrupt.\n", 5000)
idGen := func(ctx iris.Context) string {
if username := ctx.GetHeader("X-Username"); username != "" {
return username
}
return websocket.DefaultIDGenerator(ctx)
}
app.Get("/stream", websocket.Handler(server, idGen))
return server
}
func pub_thread(serve *neffos.Server){
png:= [...] byte{';',';',';',';',';'}
slice := png[:]
for{
serve.Broadcast(nil, neffos.Message{SetBinary: true, Body:slice, Namespace: "default"})
time.Sleep(1*time.Second)
}
}
Client
<html>
<button> useless button</button>
<script src="https://cdn.jsdelivr.net/npm/neffos.js@latest/dist/neffos.js"></script>
<script>
var scheme = document.location.protocol == "https:" ? "wss" : "ws";
var port = document.location.port ? ":" + document.location.port : "";
var wsURL = scheme + "://" + document.location.hostname + port + "/stream";
function handleError(reason) {
console.log(reason);
}
function handleNamespaceConnectedConn(nsConn) {
}
// const username = window.prompt("Your username?");
async function runExample() {
// You can omit the "default" and simply define only Events, the namespace will be an empty string"",
// however if you decide to make any changes on this example make sure the changes are reflecting inside the ../server.go file as well.
try {
const conn = await neffos.dial(wsURL, {
default: { // "default" namespace.
_OnNamespaceConnected: function (nsConn, msg) {
handleNamespaceConnectedConn(nsConn)
},
_OnNamespaceDisconnect: function (nsConn, msg) {
},
stream: function (nsConn, msg) { // "stream" event.
console.log(msg.Body);
console.log(msg)
}
}
},{
headers: {
"X-Username": "",
}
});
// You can either wait to conenct or just conn.connect("connect")
// and put the `handleNamespaceConnectedConn` inside `_OnNamespaceConnected` callback instead.
// const nsConn = await conn.connect("default");
// nsConn.emit(...); handleNamespaceConnectedConn(nsConn);
conn.connect("default");
} catch (err) {
handleError(err);
}
}
runExample()
</script>
</html>
Hello @StartAt24,
Does the protobuf example: https://github.com/kataras/neffos/blob/master/_examples/protobuf/main.go fits your needs? I see your point but messages containing ;
are escaped when sending from javascript client (see neffos.js). So, could you please give me a reproducible example (preferable upload to a github repository) so I can run it and resolve in order to fix any issue?
Thanks,
Gerasimos Maropoulos
Hi @kataras , run the protobuf example. I have got some problems.
When i send message from ./protobuf client
to server. The javascript client
got this problem:
If i send message fron javascript client
, the other javascript client
will receive the message, but the ./protobuf client
got nothing. And the ./protobuf server
will print remote error: proto: can't skip unknown wire type 4
. You can see it in the screenshot above.
What i want is : send binary data from 'go side' to 'javascript side'.
Hi @StartAt24, these issues were different. I fixed both of them. Message separator was not the problem. Please read:
Protobuf example updated to send data as binary with Conn.Write(Message{... SetBinary: true})
.
Thanks for the bug report and sorry for the delay, I had to publish some other packages too.