Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]Binary data contains ";" will be droped! #20

Closed
StartAt24 opened this issue Nov 21, 2019 · 3 comments
Closed

[BUG]Binary data contains ";" will be droped! #20

StartAt24 opened this issue Nov 21, 2019 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@StartAt24
Copy link

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>
@StartAt24 StartAt24 added the bug Something isn't working label Nov 21, 2019
@kataras
Copy link
Owner

kataras commented Nov 21, 2019

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

@StartAt24
Copy link
Author

StartAt24 commented Nov 25, 2019

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:

image

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'.

@kataras
Copy link
Owner

kataras commented Dec 10, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants