SignalR - connect to websocket service from javascript without SignalR library
Asked Answered
H

3

9

I have a small SignalR project that I've started that right now all it does is receives a string and echo it back to all connected users.

What I'm wondering is, since SignalR open websockets on my server - how can I connect to the service using regular websockets javascript code? (I have a reason for wanting to do it that way without the SignalR library).

I've watched using chrome developer tools and I found that the address the browser is connecting to is:

ws://localhost:53675/signalr/connect?transport=webSockets&clientProtocol=1.4&connectionToken=YKgNxA6dhmtHya1srzPPIv6KFIYEjLTFOogXqcjPErFcKCmRdjvS2X6A2KmraW%2BrLnRUNf68gYPdOkOOgJ8yRcq4iCDm%2BbUyLejsr2NySNZBvLloWuMIAvgI6oC%2Fyt%2Ba&connectionData=%5B%7B%22name%22%3A%22ophirhubtest%22%7D%5D&tid=7

How do I generate the token?

Then, it seems that the messages going between the client and server are just regular json formatted text (which will be easy to mimic):

{"C":"d-9E7D682A-A,1|E,0|F,1|G,0","S":1,"M":[]}
{"H":"ophirhubtest","M":"Echo","A":["test"],"I":0}
{"C":"d-9E7D682A-A,2|E,0|F,1|G,0","M":[{"H":"ophirHubTest","M":"printEcho","A":["You said: test"]}]}

If I just try to connect than it connects but the connection is quickly closed. If I remove the token it closes immediately.

Is it possible to connect to the WS "manually" ?

Higher answered 21/7, 2015 at 14:55 Comment(0)
C
7

Before you can connect to the server there is connection negotiation happening. This is when the server sends all the data needed to send and receive messages. Without connection negotiation you won't be able to connect to the server. Once you implement connection negotiation you will be probably half into implementing a SignalR client. I wrote a blog post describing SignalR protocol which should help you understand how things works underneath and why connecting to the server with your own websocket is not straightforward (or simply impossible if you don't follow the SignalR protocol).

EDIT

The ASP.NET Core version of SignalR now allows connecting to the server with bare webSocket.

Coed answered 21/7, 2015 at 17:4 Comment(1)
Thanks. Great article!Higher
S
6

I just want to add a that it is possible to connect to ASP.NET Core version of SignalR with websocket but you have to add the magic char 30 at the end of every call you make

const endChar = String.fromCharCode(30);
socket.send(`{"arguments":["arg1"],"streamIds":[],"target":"TestMethod","type":1}${endChar}`);
Speculum answered 29/1, 2020 at 13:40 Comment(0)
D
2

Great answers by Frédéric Thibault but there is one important thing missing. You need to send the protocol and the version directly after connecting. Otherwise you will get the error:

An unexpected error occurred during connection handshake.

Here is a full working example on how to use signalR with plain JavaScript and WebSockets:

let socket = new WebSocket("wss://your-url");

socket.onopen = function(e) {
    console.log("[open] Connection established");

    const endChar = String.fromCharCode(30);

    // send the protocol & version
    socket.send(`{"protocol":"json","version":1}${endChar}`);
};

socket.onmessage = function(event) {
    console.log(`[message] Data received from server: ${event.data}`);

    // parse server data
    const serverData = event.data.substring(0, event.data.length - 1);

    // after sending the protocol & version subscribe to your method(s)
    if (serverData === "{}") {
        const endChar = String.fromCharCode(30);
        socket.send(`{"arguments":[],"invocationId":"0","target":"Your-Method","type":1}${endChar}`);
        return;
    }

    // handle server messages
};

socket.onclose = function(event) {
    if (event.wasClean) {
        console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
    } else {
      console.log('[close] Connection died');
    }
};

socket.onerror = function(error) {
    console.log(`[error] ${error.message}`);
};
Discuss answered 10/10, 2022 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.