Websocket to the old app lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Bjarne · 2023-08-31 18:53 I have an old linux/win console app that was made with Free Pascal. It reads a large number of sensors via the RS connection and transmits control commands to the devices. Now the application should be updated to support remote connection via websocket. The program should create a connection, e.g. wss://example.org:8080 and be able to transmit and receive data. Could anyone give an example of how it could be implemented with lazarus / free pascal? ---------------------------------------------------------------------- BlueIcaro · 2023-08-31 19:26 Hi, Take a look: https://github.com/Warfley/LazWebsockets /BlueIcaro ---------------------------------------------------------------------- delphius · 2023-08-31 20:04 Quote from: Bjarne on August 31, 2023, 08:53:42 pmI have an old linux/win console app that was made with Free Pascal. It reads a large number of sensors via the RS connection and transmits control commands to the devices. Now the application should be updated to support remote connection via websocket. The program should create a connection, e.g. wss://example.org:8080 and be able to transmit and receive data. Could anyone give an example of how it could be implemented with lazarus / free pascal? Try official FCL-Web Websocket examples ---------------------------------------------------------------------- Bjarne · 2023-09-01 12:57 Thanks for the tips! My last programming dates back almost 20 years so I'm not familiar with websocket at all and it seems a bit confusing. I have also been told that Pascal would not be suitable for web programming but it is somewhat familiar from the old days so I'd like to use it. It would be nice to find commented code so it would be easier to explain these things to oneself. Sorry for the old man's questions but what is the difference between server and client? ---------------------------------------------------------------------- Bjarne · 2023-09-02 10:55 I have now tested LazWebsockets by Warfley and there are a few things I don't understand. If I run chatServer where port is 8080 and then chatClient where host is 127.0.0.1 and port is 8080 it works. But if I set EClient host as wss://127.0.0.1 or ws://127.0.0.1, I get ESocketError "Host name resolution failed". I found a binance test server in another thread. With the Chrome extension, the connection is made to the address "wss://testnet.binance.vision/ws" but with chatClient I get same host name error. What I am doing wrong? ---------------------------------------------------------------------- delphius · 2023-09-02 13:22 Quote from: Bjarne on September 02, 2023, 12:55:00 pmI have now tested LazWebsockets by Warfley and there are a few things I don't understand. If I run chatServer where port is 8080 and then chatClient where host is 127.0.0.1 and port is 8080 it works. But if I set EClient host as wss://127.0.0.1 or ws://127.0.0.1, I get ESocketError "Host name resolution failed". ws and wss is just schemes, which shows if http or tls connection should be used, TWebsocketClient.Create don't parse scheme, because LazWebsocets, as I can see from this issue use http connection only (unit ssockets), and if you want to use tls (unit opensslsockets), create TOpenSSLSocketHandler and TWebsocketClient object WebsocketClient.Connect(OpenSSLSocketHandler); QuoteWebSocket URIs    This specification defines two URI schemes, using the ABNF syntax    defined in RFC 5234 [RFC5234], and terminology and ABNF productions    defined by the URI specification RFC 3986 [RFC3986].           ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]           wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]           host =           port =           path =           query =    The port component is OPTIONAL; the default for "ws" is port 80,    while the default for "wss" is port 443.    The URI is called "secure" (and it is said that "the secure flag is    set") if the scheme component matches "wss" case-insensitively. ---------------------------------------------------------------------- delphius · 2023-09-02 13:29 Quote from: Bjarne on September 02, 2023, 12:55:00 pmI found a binance test server in another thread. With the Chrome extension, the connection is made to the address "wss://testnet.binance.vision/ws" but with chatClient I get same host name error. If you dont want to change code, try to use this example, using fcl- web, as you can see, you can select scheme you need (wss or ws) to connect to server. This is simple example, to connect, send message and disconnect from, for example, LazWebsocket server: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program example;{$mode objfpc}{$H+} uses  Classes, fpwebsocketclient, fpwebsocket, opensslsockets, sysutils; type  TRunner = class(TComponent)  public    procedure DoConnect(Sender: TObject);    procedure DoDisconnect(Sender: TObject);  end; procedure TRunner.DoConnect(Sender: TObject);begin  WriteLn(' -- Connected --');end; procedure TRunner.DoDisconnect(Sender: TObject);begin  WriteLn(' -- Disconnect --');end; var  WebSocketClient: TWebSocketClient;  Runner: TRunner;  InputMessage: string; begin  try    Runner := TRunner.Create(nil);    WebSocketClient := TWebSocketClient.Create(nil);    WebSocketClient.HostName := '127.0.0.1'; // Replace with your server's host    WebSocketClient.Port := 8080; // Replace with your server's port    WebSocketClient.Resource := '/'; // Replace with your server's resource    WebSocketClient.UseSSL := False; // Set to True if using wss    WebSocketClient.OnConnect := @Runner.DoConnect;    WebSocketClient.OnDisconnect := @Runner.DoDisconnect;    WebSocketClient.Active := True;     Write('Enter text to send: ');    ReadLn(InputMessage);    WebSocketClient.SendMessage(InputMessage);  except    on E: Exception do      WriteLn('Error: ', E.Message);  end;  WebSocketClient.Active := False;  WebSocketClient.Free;end. tls (ssl) connection is made using a third-party OpenSSL library, so you should get its binaries, for example here, but the use of this library is a native function, fpc as a whole relies on OpenSSL in the implementation of modules to work with secure functions, for example, as described here. ---------------------------------------------------------------------- delphius · 2023-09-02 13:50 Quote from: Bjarne on September 01, 2023, 02:57:50 pmI have also been told that Pascal would not be suitable for web programming This is an incorrect statement, it allows you to solve almost any tasks in the modern web, and pas2js and the future webasm + fresnel confidently allow the language to be at the forefront of progress Quote from: Bjarne on September 01, 2023, 02:57:50 pmI'm not familiar with websocket at all and it seems a bit confusing If you explain it very simply, then the reason for the appearance of the protocol is the need for reliable constant high-speed two-way data exchange between the browser and the server for real-time applications to work instead of the existing crutches that evolved from hidden frames, then through XMLHttpRequest aka AJAX to the modern Fetch API, but still remained in fact one-sided client -> web server requests. Why is http used first, which turns into a websocket by the so-called upgrade? Everything is also simple - http will be allowed everywhere, the corresponding ports are always open for it (80, 443), it will pass through any equipment, any DPI. His task is to make a normal request, establish a secure connection, and after that it will no longer be clear which packets are running there  (this is of course too simplistic and tls is not a panacea). In fact, http in this case is just as a disguise in order to eventually allow the client and server to establish a normal two-way connection through ordinary sockets, and websocket itself is a standardized way of exchanging text and binary data through these sockets, aimed at the most efficient (permanent connection + minimal meta data) and reliable (tls + ping-pong keep alive + Close Code + Close Msg) transmission of packets over TCP through a variety of modern heterogeneous networks. Quote from: Bjarne on September 01, 2023, 02:57:50 pmSorry for the old man's questions but what is the difference between server and client? Since websockets is a bidirectional protocol, the party establishing the connection is designated as the "client", but when the connection is established, both parties receive equal rights to send/receive messages and close the connection. The semantic load is usually transferred not to the role in establishing the connection, but to the functional load that the server usually serves several clients and provides some services (supports subprotocols), so it needs additional functionality (for example, a pool of multithreaded connections, authorization, etc.). In theory, it is possible to organize a serverless scheme, just with end user clients, but still, the one who will initiate the connection will be the client, and the one who will accept it will be the server until establishing the connection, all this is described in detail in RFC 6455 While I was dealing with the topic, I rewrote a few examples, maybe they will be useful to you, but they are Windows specific. For testing purposes take a look at this services: https://socketsbay.com/test-websockets Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i wss://socketsbay.com/wss/v2/1/demo/ - one way testwss://socketsbay.com/wss/v2/2/demo/ - ping pong testand https://www.postman.com/ Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i wss://ws.postman-echo.com/raw/ - ping pong test P.S. I have written a lot, if anything, correct it ---------------------------------------------------------------------- BlueIcaro · 2023-09-02 21:03 Quote from: delphius on August 31, 2023, 10:04:34 pmQuote from: Bjarne on August 31, 2023, 08:53:42 pmI have an old linux/win console app that was made with Free Pascal. It reads a large number of sensors via the RS connection and transmits control commands to the devices. Now the application should be updated to support remote connection via websocket. The program should create a connection, e.g. wss://example.org:8080 and be able to transmit and receive data. Could anyone give an example of how it could be implemented with lazarus / free pascal? Try official FCL-Web Websocket examples I didn't know that there is official version. Thanks! /BlueIcaro ---------------------------------------------------------------------- Bjarne · 2023-09-03 10:41 Thank you very much, delphius! You've helped a lot. I tested both eclient and echoclient examples for FCL-Web but I got an error fpwebsocket.pp(618,19) Error: identifier idents no member "CanRead" ---------------------------------------------------------------------- delphius · 2023-09-03 11:07 Quote from: Bjarne on September 03, 2023, 12:41:37 pmThank you very much, delphius! You've helped a lot. I tested both eclient and echoclient examples for FCL-Web but I got an error fpwebsocket.pp(618,19) Error: identifier idents no member "CanRead" For the purity of the experiment, install lazarus + fpc from trunk in a separate folder using fpcupdeluxe and check again. ---------------------------------------------------------------------- Bjarne · 2023-09-03 16:42 Big thanks once again! It works well with trunk version. I had 2.2.0 and it gave an error. ---------------------------------------------------------------------- delphius · 2023-09-03 17:11 Quote from: Bjarne on September 03, 2023, 06:42:50 pmIt works well with trunk version. I had 2.2.0 and it gave an error. You are welcome! I am glad that you managed to solve the problem ---------------------------------------------------------------------- Bjarne · 2023-09-07 19:05 I've been playing with sockets for a while now, but I still have a problem. Reading and writing of the serial port is possible with synaser, as well as data transfer via websocket, but I can't get them to work together. The question is how to transfer the data in real time. Thread?