B4J Question Websocket issues again

kostefar

Active Member
Licensed User
Longtime User
Dear Community,

For months, the below worked and would just disconnect 5 times during a day or so.
But now it´s become very difficult to get connected in the first place. The code simply mimics what´s going on at https://www.cryptopia.co.nz/Exchange, where I verified that everything is doing what it used to do by inspecting the websockets with googles developer tools.
I have also noticed that if I have two instances running, so each receiving their own token etc from the server, the point at which they finally get connected is simultaneous.

B4X:
#Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 600
#End Region

Sub Process_Globals
    Dim ws As WebSocketClient
    Private fx As JFX
    Private MainForm As Form
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
    MainForm.Show
    Init_Wshttp
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub
Sub ws_TextMessage (Message As String)
 
End Sub

Private Sub ws_Connected
    Log ("ws closed")
End Sub
Sub ws_Closed (Reason As String)
 
    Log("ws error: " & Reason)
    If ws.Connected = True Then ws.close
    Sleep(5000)
    Init_Wshttp
 
End Sub
Sub Init_Ws (input As String)
 
    Log (input)
    Dim tid As Int = Rnd(0,9)
    ws.Initialize("ws")
    Dim token As String = input.SubString(input.IndexOf("ConnectionToken")+18)
    token = token.SubString2(0,token.IndexOf($"""$)).Replace("/","%2F").Replace("+","%2B").Replace("=","%3D")
    Dim connectstring As String = ("wss://www.cryptopia.co.nz/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=" & token & "&connectionData=%5B%7B%22name%22%3A%22notificationhub%22%7D%5D&tid=" & tid)
    Log (connectstring)
    ws.Connect(connectstring)
    wait for ws_Connected
    Log("connected")
    
End Sub
Sub Init_Wshttp
    Dim httpjob As HttpJob
    httpjob.Initialize("Wsjob",Me)
 
    Dim connstring As String = ("https://www.cryptopia.co.nz/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22notificationhub%22%7D%5D&_=" & DateTime.Now)

    Log (connstring)
    httpjob.Download(connstring)
    httpjob.GetRequest.Timeout = 90000
    httpjob.GetRequest.SetHeader("Content-Type", "application/json; charset=UTF-8")
    httpjob.GetRequest.SetHeader("Referer","https://www.cryptopia.co.nz/Exchange")
    httpjob.GetRequest.SetHeader("Accept", "text/plain, */*; q=0.01")
    httpjob.GetRequest.SetHeader("Host", "www.cryptopia.co.nz")
    httpjob.GetRequest.SetHeader("X-Requested-With", "XMLHttpRequest")
    httpjob.GetRequest.SetHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36")
End Sub
Sub jobdone (job As HttpJob)
If job.Success = True Then
        Init_Ws(job.getstring)
End If
 
End Sub

The error is:

B4X:
org.eclipse.jetty.websocket.api.UpgradeException: 200 OK
    at org.eclipse.jetty.websocket.client.WebSocketUpgradeRequest.onComplete(WebSocketUpgradeRequest.java:520)
    at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:193)
    at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:185)
    at org.eclipse.jetty.client.HttpReceiver.terminateResponse(HttpReceiver.java:459)
    at org.eclipse.jetty.client.HttpReceiver.responseSuccess(HttpReceiver.java:405)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.messageComplete(HttpReceiverOverHTTP.java:297)
    at org.eclipse.jetty.http.HttpParser.handleContentMessage(HttpParser.java:606)
    at org.eclipse.jetty.http.HttpParser.parseContent(HttpParser.java:1536)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1384)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.parse(HttpReceiverOverHTTP.java:170)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:131)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:70)
    at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:130)
    at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:116)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
    at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:289)
    at org.eclipse.jetty.io.ssl.SslConnection$3.succeeded(SslConnection.java:149)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
    at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128)
    at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:199)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:673)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:591)
    at java.lang.Thread.run(Thread.java:748)
ws error: 200 OK

WHEN it´s finally connected, can happen immidiately, can take 10-20 mins or maybe more, it sits there pretty well without disconnecting.
I tried this from another computer as well, just to be sure but no luck.
In the browser, www connecting to the websockets never has this issue.
Although this indeed is an issue at server side, due to the last mentioned, I´d think there´s a way to cope with it in b4j; the websockets are fine but something changed so that b4j doesn´t "like" them anymore from this host.
I know that the cryptopia support isn´t very helpful, and takes a month to reply so I think I´m better off asking here.

Any ideas?
 
Last edited:

kostefar

Active Member
Licensed User
Longtime User
It doesn't look like an error.

Which event is raised when you see these logs?

Hi Erel,

Thanks. This is happening right after

B4X:
ws.Connect(connectstring)

In Init_Ws, and triggers ws_Closed.

8 hours ago I finally managed to start two separate apps succesfully that´s been getting the data ever since. No special reason, it just happened. But if I try to start a new one now, the problem is there again.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Any feedback on this? Should a websocket which is consistant when called from chrome not be as consistant when in b4j?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Should a websocket which is consistant when called from chrome not be as consistant when in b4j?
How do you know Chrome is consistent (never drops), but instead reconnects if necessary?
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
How do you know Chrome is consistent (never drops), but instead reconnects if necessary?

Sorry, what I ment was that Chrome is consistent in connecting immidiately. Whenever there are problems in b4j, it works right away in chrome while b4j keeps on trying again and again. But at the point where b4j makes the connection it´ll often stay connected for very long so in that sense there´s nothing wrong with the b4j connection.
 
Last edited:
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
The server should return a 101 response. If it returns 200 then the endpoint is not a websocket endpoint.

Ok, so if it always returns a 101 if accessed from a browser, but not always in b4j, what could be the reason? Then it would be for instance something with that it considers itself temporarily out of sync with the timestamp I provide, which then creates an outdated connectiontoken, making the endpoint I´m communicating to invalid. How does that sound?

Just a thought, cause otherwise i don´t see how an endpoint can be an endpoint on and off.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Many developers use jWebSocketClient to connect to websocket servers. As far as I know, you are the only one to encounter this issue so it is probably something specific to the server you are communicating with.

Why your server returns a status code 200 instead of 101? I don't know.

Thanks, so we can rule out that it´s got anything to do with the b4j implementation of websockets?
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
It is more correct to say Jetty implementation of WebSockets as jWebSocketClient is a thin wrapper above it.
It is likely that the problem is in the server side.

Appologies, that´s what I ment - it´s the source of the library. Don´t see how it could really be on server side though, when connection is always made immidiately in chrome, except for if it´s considered a server side problem that it shouldn´t have any hiccups with the jetty implementation rather than the other way around.
 
Upvote 0
Top