kataras/neffos.js

Can not we set the header in the dial?

开放

#1 创建于 2019年6月3日

 (8 条评论) (0 个反应) (0 位负责人)TypeScript (16 个派生)github user discovery
enhancementgood first issue

仓库指标

星标
 (40 个星标)
PR 合并指标
 (30 天内没有已合并 PR)

描述

I know that There is no method in the JavaScript WebSockets API for specifying additional headers for the client/browser to send. The HTTP path ("GET /xyz") and protocol header ("Sec-WebSocket-Protocol") can be specified in the WebSocket constructor.

The Sec-WebSocket-Protocol header (which is sometimes extended to be used in websocket specific authentication) is generated from the optional second argument to the WebSocket constructor:

var ws = new WebSocket("ws://example.com/path", "protocol");
var ws = new WebSocket("ws://example.com/path", ["protocol1", "protocol2"]);

The above results in the following headers: Sec-WebSocket-Protocol: protocol and Sec-WebSocket-Protocol: protocol1, protocol2

but I have error

WebSocket connection to 'ws://localhost:3811/echo' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
(anonymous) @ neffos.js:612
dial @ neffos.js:604
runExample @ (index):37
(anonymous) @ (index):59

my index.html


<input id="input" type="text" />

<button id="sendBtn" disabled>Send</button>

<pre id="output"></pre>

<script src="./neffos.js"></script>
<script>
    var scheme = document.location.protocol == "https:" ? "wss" : "ws";
    var port = ":3811"
    var wsURL = "ws://localhost:3811/echo" 
    var outputTxt = document.getElementById("output");
    function addMessage(msg) {
        outputTxt.innerHTML += msg + "\n";
    }
    function handleError(reason) {
        console.log(reason);
        window.alert(reason);
    }
    function handleNamespaceConnectedConn(nsConn) {
        let inputTxt = document.getElementById("input");
        let sendBtn = document.getElementById("sendBtn");
        sendBtn.disabled = false;
        sendBtn.onclick = function () {
            const input = inputTxt.value;
            inputTxt.value = "";
            nsConn.emit("send", input);
            addMessage("Me: " + input);
        };
    }
    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) {
                        
                    },
                    chat: function (nsConn, msg) { // "chat" event.

                    }
                }
            },["123"]);
            // 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");
            // handleNamespaceConnectedConn(nsConn);
            conn.connect("default");
        } catch (err) {
            handleError(err);
        }
    }
    runExample();
  </script>

I used Query String to solve this problem.

change wsURL to ws://localhost:3811/echo?UserId=123

and remove ["123"] protocol in the dial method.

Can not we have a custom header on dial?

function dial(endpoint: string, connHandler: any, protocols?: string[]): Promise<Conn> {
    if (endpoint.indexOf("ws") == -1) {
        endpoint = "ws://" + endpoint;
    }

    return new Promise((resolve, reject) => {
        if (!WebSocket) {
            reject("WebSocket is not accessible through this browser.");
        }


        let namespaces = resolveNamespaces(connHandler, reject);
        if (isNull(namespaces)) {
            return;
        }

        let ws = new WebSocket(endpoint, protocols);
        let conn = new Conn(ws, namespaces);
        ws.binaryType = "arraybuffer";
        ws.onmessage = ((evt: MessageEvent) => {
            let err = conn.handle(evt);
            if (!isEmpty(err)) {
                reject(err);
                return;
            }

            if (conn.isAcknowledged()) {
                resolve(conn);
            }
        });
        ws.onopen = ((evt: Event) => {
            // let b = new Uint8Array(1)
            // b[0] = 1;
            // this.conn.send(b.buffer);
            ws.send(ackBinary);
        });
        ws.onerror = ((err: Event) => {
            conn.close();
            reject(err);
        });
    });
}

Like golang client

	client, err := neffos.Dial(
		// Optional context cancelation and deadline for dialing.
		nil,
		// The underline dialer, can be also a gobwas.Dialer/DefautlDialer or a gorilla.Dialer/DefaultDialer.
		// Here we wrap a custom gobwas dialer in order to send the username among, on the handshake state,
		// see `startServer().server.IDGenerator`.
		gobwas.Dialer(gobwas.Options{Header: gobwas.Header{"X-Username": []string{username}}}),
		// The endpoint, i.e ws://localhost:8080/path.
		endpoint,
		// The namespaces and events, can be optionally shared with the server's.
		serverAndClientEvents)

贡献者指南