RTC Forums
April 26, 2024, 09:04:05 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: WebSockets : Connection closed before receiving a handshake response  (Read 11868 times)
Ecole7
RTC Expired
*
Posts: 23


« on: April 26, 2017, 02:47:55 PM »

Hello,

By implementing the WebSocket on my original project I have this following message on the Chrome browser debug window:

"WebSocket connection to 'ws://localhost/' failed: Connection closed before receiving a handshake response"

It seems to me that switching to WeSocket mode is done but as soon as the connection closes.

With the program "WSockServTest" everything is OK. Do you have any idea of the source of the problem?

Thank you in advance for your assistance.

Vincent


Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: April 26, 2017, 03:00:37 PM »

Do you have a RtcDataProvider in your Project to accept a WebSocket upgrade request and respond with a WebSocket upgrade respose?  See the "OnCheckRequest" events on the RtcDataProvider components in the WSockServTest Project.

Web Socket upgrade requests are NOT automatically accepted and responsed to by RTC components. You need a RtcDataProvider component with the OnCheckRequest event implemented to Accept a Web Socket upgrade request and send back a Web Socket upgrade response. Otherwise, Web Socket upgrade requests will fail. That same RtcDataProvider component will be receiving the OnWSConnect and all other "OnWS*" events related to that Web Socket.

Best Regards,
Danijel Tkalcec
Logged
Ecole7
RTC Expired
*
Posts: 23


« Reply #2 on: April 26, 2017, 04:43:13 PM »

Thanks for your reply,
 I checked and everything seems OK to me.
 Here is a screen copy of the Chrome debugger.
 The header contains a bizarre message "Provisional headers are shown" and it is not the same as your example
 Thank you in advance for your help.
Vincent

Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #3 on: April 26, 2017, 05:18:20 PM »

I don't see anything wrong with request headers sent by the Browser, except (maybe) that it is using the root URI '/' (I guess this is a direct copy/paste from the Example project?), but ... that's not what I meant.

What I meant, is that there is a problem with your Server implementation (Delphi code), which is required for Web Sockets to work. My guess is that you either ...

A) did NOT implement the required events on the TRtcDataRequest component, like the "OnCheckRequest" event where a Web Socket upgarde request has to be accepted and a Web Socket upgrade response should be sent back, or ...

B) did NOT link your TRtcDataProvider component with your TRtcHttpServer component, or ...

C) have multiple TRtcDataProvider components in your Server, but the CheckOrder property on the TRtcDataProvider component responsible for upgrading Web Socket requests and handling Web Socket data is too high, because of which some other TRtcDataProvider component (which is also implemented to accept '/' requests) ends up accepting that request, but does NOT send back a Web Socket upgrade response.

By the way ... instead of using 'ws://localhost/' to open the websocket, which expects your Server to be runnuing on the same machine as the Web Browser and requires the Server to reserve the root URI for Web Socket upgrade requests, you might want to use a more specific URI for Web Sockets and dinamically generate the HTML file to include the actual Server Address and URI instead of 'localhost/'.

For example, if you use 'ws://myserver.com/mywebsock' in the JavaScript code, the Browser will try to establish a HTTP connection to Server located at "myserver.com" on the default HTTP port (80). Provided you have your Server running on that domain and Port 80, you can accept that Web Socket upgrade request and send back the expected upgrade response by implementing your TRtcDataProvider components "OnCheckRequest" event like this:

  if Sender.Request.FileName='/mywebsock' then
    begin
    if Sender.Request.WSUpgrade then
      begin
      { We have recieved a Web Socket upgrade Request at '/mywebsock' }
      Sender.Accept; // Accept Request
      Sender.Response.WSUpgrade:=True; // Prepare Upgrade Response
      Sender.Write; // Send Upgrade Response
      end;
    end;

Best Regards,
Danijel Tkalcec
Logged
Ecole7
RTC Expired
*
Posts: 23


« Reply #4 on: April 26, 2017, 05:58:32 PM »

Good evening,

  I found the origin of my problem.

  I used the same RtcDataProvider for both HTTP and WEBSocket.

  I created another RtcDataProvider for the WEBSocket and the connection is OK.
 
  According to your example "WSockServTest" it seemed to me that it was not necessary to have a separate RtcDataProvider for the WEBSocket.

  Congratulations for your support very fast and accurate.
  This is very useful because it is not easy to implement WEBSockets in an existing application.

Vincent

 
 
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #5 on: April 26, 2017, 06:19:58 PM »

You don't really NEED a separate RtcDataProvider to handle Web Sockets. You could actually do everything in a single RtcDataProvider (as shown in the Example Project) if that's what you want. But, using a separate RtcDataProvider to accept and handle Web Socket requests is better than placing your entire Application code into a single RtcDataProvider, because it keeps your Application modular - for better code separation and reusability.

Best Regards,
Danijel Tkalcec
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.025 seconds with 16 queries.