#1 2022-03-10 01:30:22

Prometeus
Member
From: USA
Registered: 2020-11-20
Posts: 46

Using mORMot to access ordinary WebSocket server

Hello,

I have seen some mORMot samples showing up how to create both server and client using WebSocket, using different protocols. I created a simple client to communicate with an ordinary WebSocket server, and when I try using a 'THttpClientWebSockets' to access it when I do a 'Client.Open(WSS site, port)' I receive a 'Is a server available on this address:port? THttpClientWebSockets.OpenBind({websocket site}) [Not Found - #3]' error message. The WebSocket site is working ok, and I've tested it using one WebSocket tester website, like 'https://www.piesocket.com/websocket-tester', receiving the expected initial message.

Can an ordinary WebSocket server be accessed through mORMot using 'THttpClientWebSockets'? I tested both '80' and '443' ports that I guess are the ones to access the WebSocket server that I need because the above WebSocket tester even needs a port in the URI for accessing the server. In case that is possible, the best protocol to be used would be 'TWebSocketProtocolJson'? The server uses plain JSON to receive commands and send responses.

Thanks for any help!

Offline

#2 2022-03-10 09:13:37

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,656
Website

Re: Using mORMot to access ordinary WebSocket server

TWebSocketProtocolJson is a high-level protocol emulating REST/HTTP calls over WebSockets.
If the server does not understand it, it is pointless to be used.

You need to use another protocol, e.g. the TWebSocketProtocolChat, which is about receiving and sending low-level WS frames.

Offline

#3 2022-03-10 16:23:03

Prometeus
Member
From: USA
Registered: 2020-11-20
Posts: 46

Re: Using mORMot to access ordinary WebSocket server

Thanks for the suggestion about the best protocol in my case.

However, I can't test that point because I am stuck on try connecting to the server. I can't test the rest of my code because I can't go on from the connection phase. I tried different WebSockets servers and the result was always the same ('Is a server available on this address:port? THttpClientWebSockets.OpenBind({websocket site}) [Not Found - #3]'):

var ClientWS         : THttpClientWebSockets;
    WSSConnection : TGetWSSRequests;
    lProto               : TWebSocketProtocolChat;

begin 
  WSSConnection := TGetWSSRequests.Create;
  ClientWS := THttpClientWebSockets.Create;
  ClientWS.OnCallbackRequestProcess := WSSConnection.DealWSSRequests;
  ClientWS.Open('wss://socketsbay.com/wss/v2/2/demo','443'); //                        <--- HERE it raises the error I told in my first message
...

  I don't need a REST WebSocket in my case, and that's why I am using 'THttpClientWebSockets'. Unfortunately, while I tried looking through the mORMot 2 source code and samples, I didn't find the right way to work with 'THttpClientWebSockets' so far. I thought it was like 'TSimpleHttpClient' with the particularities of 'WebSockets', eg. the callback functions. All samples that I saw about this matter were using both server and client using mORMmot. I didn't see a sample for using WebSockets to talk to an ordinary WebSocket server.

Last edited by Prometeus (2022-03-10 21:13:33)

Offline

#4 2022-03-10 18:07:10

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,656
Website

Re: Using mORMot to access ordinary WebSocket server

You are making a confusion between socket address and HTTP URI.
'wss://socketsbay.com/wss/v2/2/demo' is an URI.
But Open() expects an address, i.e. a server host name or ip.

So you should write Open('socketbay.com', '443', nlTcp, 10000, true) with aServer being the computer address, and aTLS=true for wss like connection.
Then call WebSocketsUpgrade('wss/v2/2/demo'... with the proper protocol.

Offline

#5 2022-03-10 21:16:08

Prometeus
Member
From: USA
Registered: 2020-11-20
Posts: 46

Re: Using mORMot to access ordinary WebSocket server

Indeed, I was mixing those pieces of information. Thanks!

Offline

#6 2022-03-13 15:14:20

Prometeus
Member
From: USA
Registered: 2020-11-20
Posts: 46

Re: Using mORMot to access ordinary WebSocket server

I am still doing some tests with mORMot WebSockets but for some reason, I am getting 'Invalid HTTP Upgrade Header' after upgrading to WebSocket. I tried with five different WebSocket servers that I found on Internet, but for only one of them, the result was ok, although they are all supposed to respond the same way, with JSON or plain text.

I did a simple test program here https://github.com/PrometeusRec/mormot_ … t_Test.dpr where you can see the five websites above, and uncomment one website at a time and test it. Currently, only the last one is giving an answer different from 'Invalid HTTP Upgrade Header' after calling 'WebSocketsUpgrade'. I tested all those websites on 'https://www.piesocket.com/websocket-tester#' and all worked as expected. For two of those, you can enter the JSON  in the comments if you want to see them respond, as all the others will give an automatic response right after the connection.

What is the proper method to send a text back to the server using the bi-direction open connection? Thanks!

Offline

#7 2022-03-14 03:33:29

Prometeus
Member
From: USA
Registered: 2020-11-20
Posts: 46

Re: Using mORMot to access ordinary WebSocket server

I verified that for the following line (451 - mormot.net.ws.client):

  if not IdemPChar(pointer(cmd), 'HTTP/1.1 101') or
         not (hfConnectionUpgrade in Http.HeaderFlags) or
         (Http.ContentLength > 0) or
         not IdemPropNameU(Http.Upgrade, 'websocket') or
         not aProtocol.SetSubprotocol(prot) then
        exit;

All five tests fail for "(Http.ContentLength > 0)", and only the last case passes for "not aProtocol.SetSubprotocol(prot)"

Still trying to figure out why it doesn't upgrade for the first four cases

Offline

#8 2022-03-14 07:55:52

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,656
Website

Re: Using mORMot to access ordinary WebSocket server

IIRC a HTTP/1.1 upgrade should have no content-length by definition.

What is the input headers content?

Perhaps the client has some unexpected headers.

Offline

#9 2022-03-14 13:57:04

Prometeus
Member
From: USA
Registered: 2020-11-20
Posts: 46

Re: Using mORMot to access ordinary WebSocket server

ab wrote:

IIRC a HTTP/1.1 upgrade should have no content-length by definition.

So that test had really passed!

What is the input headers content?

Perhaps the client has some unexpected headers.

Input headers were empty

Based on the test done by 'aProtocol.SetSubprotocol(prot)', I realized that the problem was when creating an instance of 'TWebSocketProtocolChat', where I was giving a name when calling 'Create'. It was not clear to me, based on the comments in the source code, what 'aName' meant exactly, and I thought it was a name the programmer was giving to that specific use. When I left it empty it passed the test done at line 451 (above) and worked as expected.

--> What is the proper method to send a text back to the server using the bidirectional open connection? Thanks!

Offline

#10 2022-03-14 14:34:31

Prometeus
Member
From: USA
Registered: 2020-11-20
Posts: 46

Re: Using mORMot to access ordinary WebSocket server

Prometeus wrote:

--> What is the proper method to send a text back to the server using the bidirectional open connection? Thanks!

   Nevermind, I made it using 'SendFrames'

Offline

Board footer

Powered by FluxBB