I am using Typescript on a next.js implementation of a client.
I am working on a connection to an Azure SignalR websocket. It's authenticated with a token and i am able to connect and ping successfully. I even get pongs back. However, I don't get the actual messages I am looking for - nothing gets received on the on(message) method.
I don't have access to the code of the server, but i do have a reference implementation and that does get the pong messages and the data message
Could the server be limited to broadcasting to one session ? or one session at a time - I am connecting with the same account, though the Auth token is different
I am quite stuck. I have duplicated all the inputs of the reference implementation, the socket connects and as i said , i send pings and get pongs back, but no data.
Note that the JWT token is passed in the url (wsUrl)
const websocketInstance = new WebSocket(wsUrl, {
headers: {
Host: "******.signalr.net",
"Accept-Language": "en-GB,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Sec-WebSocket-Version": "13",
Origin: "********.com",
"Sec-WebSocket-Extensions": "permessage-deflate",
"Sec-WebSocket-Key": "********",
Connection: "keep-alive, Upgrade",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "websocket",
"Sec-Fetch-Site": "cross-site",
Pragma: "no-cache",
"Cache-Control": "no-cache",
Upgrade: "websocket",
});
websocketInstance.on("open", () => {..}
websocketInstance.on("message", (data) => {..}
websocketInstance.on("pong", (data) => {..}
websocketInstance.on("error", (error) => {..}
...
}
As you're successfully connecting to Azure SignalR and getting pong responses, but you're not receiving actual messages.
This happens because you're connecting directly via WebSockets (wss://
), but SignalR requires an initial negotiation over https://
.
So, use https://
Instead of wss://
POST
request to https://your-signalr-service.signalr.net/client/negotiate
.url
and accessToken
from the response.wss:// URL
for your WebSocket connection.Here's a sample code:
async function connectWebSocket() {
const response = await fetch("https://your-signalr-service.signalr.net/client/negotiate", {
method: "POST",
headers: { "Content-Type": "application/json" },
});
const { url, accessToken } = await response.json();
const websocketInstance = new WebSocket(`${url}?access_token=${accessToken}`);
websocketInstance.onopen = () => {
console.log("WebSocket connection opened");
};
websocketInstance.onmessage = (event) => {
console.log("Message received:", event.data);
};
websocketInstance.onclose = () => {
console.log("WebSocket connection closed");
};
websocketInstance.onerror = (error) => {
console.error("WebSocket error:", error);
};
return websocketInstance;
}
connectWebSocket();
Please refer this doc for better understanding about Azure SignalR Service.
As an alternative, you can use @microsoft/signalr
instead of raw WebSockets, as it handles negotiation, tokens, and reconnection automatically.