KthProg
KthProg

Reputation: 2117

WebSocket is closed immediately

When I open a WebSocket in React Native, it is closed immediately. There is no code or reason. It also receives an error which has no message. I am using WebSockets through an ngrok http tunnel. My server receives the request and completes the connection. If I send data immediately, it will be received, but about 1/4 of a second later, the connection is closed and I cannot send any data. I then receive an error server-side saying the connection was closed without completing the handshake. What am I doing wrong? This is on Android.

C# server code:

app.Use(async (context, next) => {
    if (!context.Request.Path.ToString().Contains("/notifications/")) 
    {
        await next();
        return;
    }
    if (context.WebSockets.IsWebSocketRequest) {
        WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
    } else {
        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
    }
});

JS Client Code:

import Defaults from "../Defaults";
import Services from "../Services";

export default class NotificationService {
    constructor(){
        this.socket = null;
    }

    subscribe(userId, onmessage){
        let url = Defaults.webRoot.replace('http', 'ws') + '/notifications/' + userId;
        this.socket = new WebSocket(url);
        this.socket.onmessage = onmessage;
        this.socket.onerror = this.onerror;
        this.socket.onclose = this.onclose;
        this.socket.onopen = this.onopen;
    }

    onerror(event){
        alert('ws error: ' + event.message);
    }

    onclose(event){
        alert('ws closed: ' + event.code + ' - ' + event.reason);
    }

    onopen(event){
        alert('ws opened');
    }
}

onclose shows 'ws closed: undefined - undefined'.

I use the socket in a later request, but I have to assume the socket isn't just closed immediately once the request is completed, that would be stupid.

The state is Open by the time it gets to my code that sends messages. Yet it is obviously closed and does not receive messages on the client side.

Upvotes: 3

Views: 4680

Answers (1)

KthProg
KthProg

Reputation: 2117

I figured it out. If I complete the request, this for some reason also closes the web socket. There must be something coming back in the response that confuses the web socket, although I assumed the request and the socket itself would be two totally different things.

I basically have to add this line to keep the socket alive: while (!webSocket.State.HasFlag(WebSocketState.Closed) && !webSocket.State.HasFlag(WebSocketState.Aborted)) {}

I'm really not sure what that will do to performance and I'm concerned that I have to do that. I suppose you could make it slightly less terrible with a Thread.Sleep call in the while loop.

Hopefully, someone understands this problem better, and knows how to better fix the issue.

Upvotes: 0

Related Questions