Lazarus

Announcements => Third party => Topic started by: Warfley on February 18, 2020, 10:01:33 pm

Title: Websockets Server/Client Implementation
Post by: Warfley on February 18, 2020, 10:01:33 pm
Hey,

for a project I required a websocket server to communicate with an web application. From a first glance I wasn't really satisfied with the few results I found on google didn't really satisfy me, so I've wrote my own.

Github Page (https://github.com/Warfley/LazWebsockets)

It works fully using the fcl ssockets unit and is therefore cross plattform available without any additional packages or components (like indy or synapse) required.

Also, once the protocol was implemented for the server it was only a small step to implement also a client, so this provides an implementation for a Server and a Client.

For further details see the Readme.md on github.

For my little project for which has only to handle a few connections in a local network and everyone is nice it's now working fine, I haven't been able to test it on a larger scale. If you run into problems with it, feel free to open an issue on github or post here.
Title: Re: Websockets Server/Client Implementation
Post by: edwinyzh on March 01, 2020, 04:34:56 am
Well done!
Thanks for sharing!
Does it fully implement the Websockets protocol standard?
Title: Re: Websockets Server/Client Implementation
Post by: MarkMLl on March 01, 2020, 10:42:39 am
Nicely done. I wonder whether that would work with Mycroft?

https://mycroft-ai.gitbook.io/docs/mycroft-technologies/mycroft-core/message-bus

MarkMLl
Title: Re: Websockets Server/Client Implementation
Post by: Zath on March 01, 2020, 11:34:20 am
Thanks for sharing this, very interesting.
Title: Re: Websockets Server/Client Implementation
Post by: Warfley on March 05, 2020, 04:37:02 am
Does it fully implement the Websockets protocol standard?
Mostly, it does not:
1. provide any support for extensions (i.e. no mechanism like overloading some functions or so), so any extensions need to be implemented on the source level.  I'm actually currently thinking about a nice method to implement this neatly..
2. check for the validity of UTF-8 String message. It will simply copy the bytes. The protocol requires to fail the connection in case of malformed UTF-8, which right now is currently in the responsibility of the user (i.e. if you get an error processing the messages, you need to call close explicitly). So just from a technical point of view byte messages and String messages are handled identical.
3. provide a special mechanism for  subprotocols. They need to be implemented by the User, i.e. in the TWebsocketHandler (by overriding the Accept method you also can influence the handshake), but I don't know enough about the subprotocols to know if this is sufficient.
4. Support Messages in Close-Frames like statuscodes, while this is actually not hard to implement, it's something I hadn't time to do.
5. Use websocket URI's but requires you to provide the host, port and path (including the query) directly
And lastly, using fragmented Frames, while implemented, is currently kinda pointless, as the implementation works on a message basis (for having seamless threading support), meaning the messages get buffered anyway. But controll messages are still handled, even when waiting for fragments of another message

Besides those points this should be standard compliant. But I worked more on an example basis and only superficially read through the standard and the only parts I've read in depth where the most important core protocol features.

Nicely done. I wonder whether that would work with Mycroft?
https://mycroft-ai.gitbook.io/docs/mycroft-technologies/mycroft-core/message-bus
From what I've seen this simply uses Json-Messages on top of websocket UTF-8 messages, so I don't see why it should not work. You could define a class which owns the TWebsocketCommunincator, as well as a class hierachy for the Mycroft Message types, and simply wrap it. So your wrapper class subscribes to TWebsocketCommunincator.OnRecieveMessage, recieves the messages, loads the json, and than creates the respected Mycroft message from it. Similarly it can provide a write method, which takes such a mycroft message, converts it to json and writes it to the TWebsocketCommunincator.WriteData stream.


There are also a few things I should mention: For one, it can handle SSL, but I have no idea how, as the ssockets Unit has nearly no documentation and all of my knowledge about it comes from looking at fpHttpClient. Thats why I provide ras access to the TSocketHandler, so you can still use it, if you know how. For me this isn't currently a problem, as I only need the server, which is behind an NGINX reverse proxy, who does all the HTTPS stuff.
The second thing to keep in mind with this library is that it is very conservative in terms of Threading, while it is thread safe (i.e. there can't be any problems from calling the send/recieve/close functions in parallel), it does not make any assumptions what runs on what Thread. I did this because I didn't want to rely on Synchronize or TThread.Queue, because I didn't want that library to be dependend on the user calling CheckSynchronize regularly. So if you want to lift messages to the main thread, you need to call Synchronize seperately. My application does mostly MySQL stuff, which is also thread safe, so I don't care which threads recieve and send messages. But if you are for example writing an LCL application, you might want to use synchronize or TThread.Queue


While for my purposes this is currently enough, if you wish for additional features, feel free to leave a ticket at Github, I will try to keep this library as general as possible to be able to cover many use cases, so feedback is highly appreciated, especially for cases which I haven't thought of before
Title: Re: Websockets Server/Client Implementation
Post by: mr-highball on March 05, 2020, 04:36:20 pm
Just found this and am really happy you put the time into it (and better yet, shared it). Multiple occasions I could've used a websocket library and there just wasn't any good option.
Title: Re: Websockets Server/Client Implementation
Post by: jsonnabend on April 25, 2020, 05:30:29 pm
Thanks for sharing this. I got it to compile in half a second and was receiving messages from the sample webpage you included.

I can't figure out how to push messages from the server back to the browser client. Any help?

Thanks again.
Title: Re: Websockets Server/Client Implementation
Post by: RG on July 02, 2020, 02:49:04 pm
Thanks for sharing
I was looking for something like this. I just tested the examples one server and two clients and I noticed the CPU load goes up to 52 percent when I open the second client, when I close the clients then the load on the CPU is even greater close to 100 percent. The tests were done with Windows 10.
What could be the problem?
Title: Re: Websockets Server/Client Implementation
Post by: Warfley on July 08, 2020, 02:38:47 pm
Thanks for sharing
I was looking for something like this. I just tested the examples one server and two clients and I noticed the CPU load goes up to 52 percent when I open the second client, when I close the clients then the load on the CPU is even greater close to 100 percent. The tests were done with Windows 10.
What could be the problem?
Are you using the latest version of the master branch?

Because I "fixed" this problem (as was reported in this issue: https://github.com/Warfley/LazWebsockets/issues/9) on May 29th

Thanks for sharing this. I got it to compile in half a second and was receiving messages from the sample webpage you included.

I can't figure out how to push messages from the server back to the browser client. Any help?

Thanks again.

Check out the server example: https://github.com/Warfley/LazWebsockets/blob/ce3bcc1da0c6121236d32743018b2ba0a253a1ec/examples/chatServer.pas#L51
Title: Re: Websockets Server/Client Implementation
Post by: RG on July 08, 2020, 07:50:29 pm
Quote
Are you using the latest version of the master branch?

Because I "fixed" this problem (as was reported in this issue: https://github.com/Warfley/LazWebsockets/issues/9) on May 29th

To be sure I downloaded again -> tested again -> got the same result.

Thanks

Title: Re: Websockets Server/Client Implementation
Post by: Warfley on July 09, 2020, 09:20:56 pm
In wsutil.pas in line 462 you find a Sleep(0), replace the 0 with a positive number (e.g. 5 or 10, maybe even 100) and check it again.
You can also try to uncomment the TThread.yield() before the sleep.

Sadly I don't have much time currently at hand to do the debugging myself, but I suspect this to be the issue.
Title: Re: Websockets Server/Client Implementation
Post by: RG on July 10, 2020, 11:47:47 am
Ok, I will try that.

Thank You
Title: Re: Websockets Server/Client Implementation
Post by: hgbk on February 25, 2021, 02:56:19 pm
Not sure whether this gets attention after 1 year of silence, nevertheless:
1) great work! Thanks! Gives e the hope to solve my problem.
2) question: when I start and connect the html client several times, how can I differnetiate betwenn the 4 connections, e.g. to send different messages to each of them?

(a beginner in websockets)
Title: Re: Websockets Server/Client Implementation
Post by: hgbk on February 28, 2021, 12:56:57 pm
Not sure whether this gets attention after 1 year of silence, nevertheless:
1) great work! Thanks! Gives e the hope to solve my problem.
2) question: when I start and connect the html client several times, how can I differnetiate betwenn the 4 connections, e.g. to send different messages to each of them?

(a beginner in websockets)

Though I still don’t know how to identify TWebsocketCommunincator during Connect, I found a workaround  which solves my specific problem:
I identify the TWebsocketCommunincator during the first message received from a specific client and assign it to an array of TWebsocketCommunincator (:= TWebsocketCommunincator(Sender)). So I can send separate messages to the different clients.
Title: Re: Websockets Server/Client Implementation
Post by: Warfley on March 02, 2021, 09:29:52 pm
First of all, just found a little bit of time to update this project again. Fixed the thread pooling issues that resulted in 100% CPU load, as well as a few other bugs.

Though I still don’t know how to identify TWebsocketCommunincator during Connect, I found a workaround  which solves my specific problem:
I identify the TWebsocketCommunincator during the first message received from a specific client and assign it to an array of TWebsocketCommunincator (:= TWebsocketCommunincator(Sender)). So I can send separate messages to the different clients.

I answered you in your issue, but here again, with a little bit more detail. Previously the library did not track the open connections, you had to do it yourself, like with the array you are using. So what you did is actually how it was intendet. That said, I changed this, now the Handler has a thread safe list of active connections.

To identify a connection you have different options. The first one would be to look at the remote address and port (ACommunication.SocketStream.RemoteAddress.Address and ACommunication.SocketStream.RemoteAddress.Port). This combination is unique for every connection.

Another possibility is to have some form of identifier, for example upon connection your client could send a message like 'NAME=XXX' or something like that and you can read that message and then just store an association between name and the TWebsocketCommunicator object somewhere. For this you can for example use a TFPGMap, TDictionary or if performance does not matter to you and you don't want to use generics, TStringList.
BUT: when you have a threaded application, remember that you need to use thread safe objects. You can look at how the thread save connection list is managed within my TWebsocketHandler class. For further information I recommend you reading this wiki article, because multithreaded applications are not so simple: https://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial#Critical_sections
Title: Re: Websockets Server/Client Implementation
Post by: hgbk on March 10, 2021, 04:42:23 pm
Thanks a lot for your great efforts!!

Actually I'm still in the development and testing mode, in which I start the clients from my browser and therefore different to life situations the client instances show the same IP adress, port.

Therefore I used the alternative ("another possibility") in which I do the identification protocol in the transfer message ("Name=XXX"). This works well in my case.

Client (JavaScript) and server (Pascal) are ready now, connection via websockets is established and 1st transfer from client to server work. now it's time to debug ...

Thanks again!!!
Title: Re: Websockets Server/Client Implementation
Post by: senglit on March 04, 2022, 04:39:53 pm
First thanks for your contribution. Now I'm using this package to develop a simple app. And I got a small problem with identify different clients.
A part of my code on server side like this:
Code: Pascal  [Select][+][-]
  1. procedure TSocketHandler.DoHandleCommunication(ACommunication: TWebsocketCommunicator);
  2. var
  3.   str: string;
  4.   conn: TWSConnection;  // i store the usename combined with its TWebsocketCommunicator and some user data by a TList of TWSConnection
  5.   i, msgCount: integer;
  6. begin
  7.   WriteLn('Connected to ', ACommunication.SocketStream.RemoteAddress.Address,
  8.     ':', ACommunication.SocketStream.RemoteAddress.Port);
  9.   ACommunication.OnReceiveMessage := @MessageReceived;
  10.   ACommunication.OnClose := @ConnectionClosed;
  11.   while ACommunication.Open do begin
  12.     if not GetConnByCommunicator(ACommunication, conn) then continue;
  13.     msgCount := conn.writeMsg.Count;
  14.     if msgCount > 0 then begin
  15.       for i := 0 to msgCount - 1 do ACommunication.WriteStringMessage(conn.writeMsg[i]);
  16.       for i := 0 to msgCount - 1 do conn.writeMsg.Delete(0);
  17.     end;
  18.   end;
  19. end;    
  20.  
Now I run the server together with 2 clients on the same computer. It looks ok  but only a little problem.
this is a part of writeln message of the server:
Code: Text  [Select][+][-]
  1. Message from 127.0.0.1:663 - { "token" : "C05115C4274C437C9F382291AC0C03D2", "msgtype" : "subscribe", "boxname" : "box0" }
  2. Message from 127.0.0.1:663 - { "CoilOut" : "00000000", "CoilIn" : "00000000", "Humidity" : "14.5", "Temperature" : "30.2", "AC current" : "0.09", "AC voltage" : "228", "DC voltage" : "25.35", "msgtype" : "report", "token" : "3BB7235907AE4C76A432F8826623D9E7" }
  3.  

The first message is sent by client1 as a controller. The second message is sent by client2 as a sensor hub. Client1 send a "subscribe" command to the sever, and the server dispatch it to client2, then client2 start to send sensor values to server every second and server will dispatch them to client1. The whole work flow is ok except: Client1 and Client2 got the same address and port!!!

I think the ports should be given by operation system and it should not be the same. but that's what I got on my screen :o

when I disconnect client1, the server knows and writeln 127.0.0.1:663(client1) is disconnected. client2(also 127.0.0.1:663) is still there. it's not influnced by the disconnection of client1 even they have the same ip and port. I'm really confused. Till now this problem dosen't cause any runtime problem. But I afraid of potential problem since I can't explain it.

why?

First of all, just found a little bit of time to update this project again. Fixed the thread pooling issues that resulted in 100% CPU load, as well as a few other bugs.

Though I still don’t know how to identify TWebsocketCommunincator during Connect, I found a workaround  which solves my specific problem:
I identify the TWebsocketCommunincator during the first message received from a specific client and assign it to an array of TWebsocketCommunincator (:= TWebsocketCommunincator(Sender)). So I can send separate messages to the different clients.

I answered you in your issue, but here again, with a little bit more detail. Previously the library did not track the open connections, you had to do it yourself, like with the array you are using. So what you did is actually how it was intendet. That said, I changed this, now the Handler has a thread safe list of active connections.

To identify a connection you have different options. The first one would be to look at the remote address and port (ACommunication.SocketStream.RemoteAddress.Address and ACommunication.SocketStream.RemoteAddress.Port). This combination is unique for every connection.

Another possibility is to have some form of identifier, for example upon connection your client could send a message like 'NAME=XXX' or something like that and you can read that message and then just store an association between name and the TWebsocketCommunicator object somewhere. For this you can for example use a TFPGMap, TDictionary or if performance does not matter to you and you don't want to use generics, TStringList.
BUT: when you have a threaded application, remember that you need to use thread safe objects. You can look at how the thread save connection list is managed within my TWebsocketHandler class. For further information I recommend you reading this wiki article, because multithreaded applications are not so simple: https://wiki.lazarus.freepascal.org/Multithreaded_Application_Tutorial#Critical_sections
Title: Re: Websockets Server/Client Implementation
Post by: Warfley on March 06, 2022, 06:23:24 pm
This is really quite weird, this means that something went horribly wrong (either the capturing of IP and port by the underlying ssockets lib is broken, or there is some memory management issue that both point to the same address, or some very weird caching bug), whatever it is, this should never happen.

If I have some free time I will investigate this. May I ask what OS you are using?
Title: Re: Websockets Server/Client Implementation
Post by: senglit on March 11, 2022, 04:07:14 pm
I'm using win10 lazarus2.2.0 with fpc 3.2.2

and here is the server writeln part:
Code: Pascal  [Select][+][-]
  1. procedure TSocketHandler.MessageReceived(Sender: TObject);
  2. var
  3.   Messages: TWebsocketMessageOwnerList;
  4.   m: TWebsocketMessage;
  5.   Comm: TWebsocketCommunicator;
  6.   jo: TJSONObject;
  7.   func, utype, uname, pwd, token: string;
  8.   msg, val, res: string;
  9.   conn: TWSConnection;
  10.   cp: PWSConnection;
  11. begin
  12.   Comm := TWebsocketCommunicator(Sender);
  13.   Messages := TWebsocketMessageOwnerList.Create(True);
  14.   jo := TJSONObject.Create;
  15.   try
  16.     Comm.GetUnprocessedMessages(Messages);
  17.     for m in Messages do begin
  18.       if m is TWebsocketStringMessage then begin
  19.         msg := TWebsocketStringMessage(m).Data;
  20.         WriteLn('Message from ', Comm.SocketStream.RemoteAddress.Address,
  21.           ':', Comm.SocketStream.RemoteAddress.Port, ' - ', msg);
  22.         jo := GetJSON(msg) as TJSONObject;
  23.         func := jo.Get('msgtype');
  24.         if func = 'gettoken' then begin
  25.           utype := jo.Get('usertype');
  26.           uname := jo.Get('uname');
  27.           pwd := jo.Get('upassword');
  28.           token := GenToken(utype, uname, pwd);
  29.           ConfirmConn(uname, token, comm);
  30.           jo.Clear;
  31.           jo.Add('msgtype', 'tokenreturn');
  32.           jo.Add('token', token);
  33.           res := jo.AsJSON;
  34.           Comm.WriteStringMessage(res);
  35.         end else begin
  36.           if not GetConnByCommunicator(comm, conn) then continue;
  37.           if conn.utype <> 'monitor' then begin
  38.             GetConnsByType('monitor', monitorList);
  39.             for cp in monitorList do begin
  40.               if cp^.token = '' then continue;
  41.               cp^.writeMsg.Add(msg);
  42.             end;
  43.           end else begin
  44.             if func = 'subscribe' then begin
  45.               val := jo.Get('boxname');
  46.               if val = null then continue;
  47.               if not GetConnByUname(val, conn) then continue;
  48.               jo.Clear;
  49.               jo.Add('msgtype', 'subscribe');
  50.               jo.Add('switch', 'on');
  51.               res := jo.AsJSON;
  52.               conn.writeMsg.Add(res);
  53.               jo.Clear;
  54.               jo.Add('msgtype', 'forcereport');
  55.               res := jo.AsJSON;
  56.               conn.writeMsg.Add(res);
  57.             end else if func = 'unsubscribe' then begin
  58.               val := jo.Get('boxname');
  59.               if val = null then continue;
  60.               if not GetConnByUname(val, conn) then continue;
  61.               jo.Clear;
  62.               jo.Add('msgtype', 'subscribe');
  63.               jo.Add('switch', 'off');
  64.               res := jo.AsJSON;
  65.               conn.writeMsg.Add(res);
  66.             end;
  67.           end;
  68.         end;
  69.       end else begin
  70.         msg := TWebsocketStringMessage(m).Data;
  71.         //i don't know how to handle messages like ping pong close.... just leave it here
  72.       end;
  73.     end;
  74.   finally
  75.     Messages.Free;
  76.     jo.Free;
  77.   end;
  78. end;
  79.  
Title: Re: Websockets Server/Client Implementation
Post by: senglit on March 15, 2022, 03:55:38 am
Today I stopped the sensor hub client and opened 2 controler clients at the same computer.

The sever says that it accepted connection for 2 times at the same ip and port. My code take them as 2 connections and saved it in monitorList(a TList with infomation of each connection). When the server needs to dispatch messges to clients, it send message to all of the connections in that TList. And then the sever raised an error.

By the way, this "Stream already closed" error always raise at connection broken. I tried to contain it in a "try except" but it still raised and the "except" part did not run. So I can't delete the broken connction from monitorList. I guess it would be a big problem.

The way the server acted is diffrent from that when I openned 1 sensor hub client and 1 controller clients.
Title: Re: Websockets Server/Client Implementation
Post by: senglit on March 15, 2022, 06:16:54 am
The sever says that it accepted connection for 2 times at the same ip and port. My code take them as 2 connections and saved it in monitorList(a TList with infomation of each connection). When the server needs to dispatch messges to clients, it send message to all of the connections in that TList. And then the sever raised an error.

My bad. This problem is not caused by your package but my own code. I allow one user to login 2 times and when one of them logout I closed all of the connection bind with that user name. But If I login with 2 different user name and password, these 2 connections do have the same ip and port.

And  a "try except" cann't  the exception problem is still there. Does it happen because I wrote websocket server in a thread?
Title: Re: Websockets Server/Client Implementation
Post by: Warfley on March 16, 2022, 12:07:06 pm
Try except should pretty much always work, but if you are using Lazarus, it will throw the message that an exception has been risen even if the exception will be cought. Just click the continue button so the except block will be executed. This is just a little annoyance with Lazarus
Title: Re: Websockets Server/Client Implementation
Post by: MarkMLl on March 16, 2022, 12:56:09 pm
Try except should pretty much always work, but if you are using Lazarus, it will throw the message that an exception has been risen even if the exception will be cought. Just click the continue button so the except block will be executed. This is just a little annoyance with Lazarus

I'm not sure this invariably applies, but I don't think that the main program's exception handler will catch an exception thrown in a dynamically-linked library.

MarkMLl
Title: Re: Websockets Server/Client Implementation
Post by: Warfley on March 17, 2022, 07:36:07 pm
Found the problem with the identical port, I used the wrong identifier (LocalPort rather than RemotePort) pushed a fixed version to the github
Title: Re: Websockets Server/Client Implementation
Post by: senglit on March 18, 2022, 05:59:03 am
Found the problem with the identical port, I used the wrong identifier (LocalPort rather than RemotePort) pushed a fixed version to the github

problem solved, 2 clients from the same computer got the different port now:
Code: Text  [Select][+][-]
  1. box 14117 2022-03-18 11:53:02 192.168.115.212:38659
  2. Connected to 127.0.0.1:25546
  3. Message from 127.0.0.1:25546 - { "func" : "gettoken", "uname" : "root", "upassword" : "123456" }
  4. box 14117 2022-03-18 11:53:03 192.168.115.212:38659
  5. box 14117 2022-03-18 11:53:04 192.168.115.212:38659
  6. Connected to 127.0.0.1:26314
  7. Message from 127.0.0.1:26314 - { "func" : "gettoken", "uname" : "aaa", "upassword" : "aaa" }
  8. box 14117 2022-03-18 11:53:05 192.168.115.212:38659
  9.  
Title: Re: Websockets Server/Client Implementation
Post by: senglit on March 19, 2022, 05:53:57 pm
Is this a bug?

I was testing my app and wanted to see what would happen if I connect the websocket server from a web browser.

This is how I set my server:
Code: Pascal  [Select][+][-]
  1.   socket := TWebSocketServer.Create(8888);
  2.   socket.RegisterHandler('*', '/ws', handler, True, True);
  3.  

When I connected from web browser with http://127.0.0.1/ I got an message "connection request rejected" like conneting to any other unavailable website. It's ok.

But when I connected with http://127.0.0.1:8888/ws or http://127.0.0.1:8888 the web socket server took arount 1 minute and raised an exception like the attached
image. After I click "continue" the web browser got and "Not a Websocket Request" message. If I ran my app without debugger nothing looks unnormal, the exception must be ignored automaticly.
Title: Re: Websockets Server/Client Implementation
Post by: Warfley on March 24, 2022, 09:13:56 pm
Yes, this is expected behavior, this is not an HTTP webserver, it can only handle Websocket connections, anything else will cause the Not a Websocket Request to be launched. The 1 minute delay is kinda weird though, will check it if i have time on the weekend
Title: Re: Websockets Server/Client Implementation
Post by: senglit on March 25, 2022, 03:12:55 pm
A little advise.

Do you think it's a good idea to add this into TWebsocketCommunicator? So that user can new his/her own dataset on TSocketHandler.Accept and dispose it on TSocketHandler.ConnectionClosed and I think it will be more convinient for user to handle their connection-related data than using TFPGMap.
Code: Pascal  [Select][+][-]
  1. UserData:PtrInt;
  2.  

Edit:
oh, there is no TWebsocketCommunicator yet when Accept. But user can new his/her dataset at TSocketHandler.DoHandleCommunication when something like "login" received.
Title: Re: Websockets Server/Client Implementation
Post by: Warfley on March 25, 2022, 04:57:28 pm
Actually, making the WebsocketCommunicator better extensible is something that was already suggested earlier. I am not so keen on simply adding a PtrInt field to it, because this is not such a clean solution. What was suggested before is to have the ability to create a custom class that inherits from TWebsocketCommunicator and can be extended with custom data or functions.

I just added this feature, see the BroadcastServer example for how to use it.

I also changed up the ConnectionList, which I previously added to the SocketHandler base class, but I think that this is too restrictive, as there might be the need for other datastructures (like a map mapping an identifier to the Object), so this is something the SocketHandler now has to manage manually (see BroadcastServer as an example).
Title: Re: Websockets Server/Client Implementation
Post by: senglit on March 30, 2022, 06:38:00 am
Tried and worked fine.

Actually, making the WebsocketCommunicator better extensible is something that was already suggested earlier. I am not so keen on simply adding a PtrInt field to it, because this is not such a clean solution. What was suggested before is to have the ability to create a custom class that inherits from TWebsocketCommunicator and can be extended with custom data or functions.

I just added this feature, see the BroadcastServer example for how to use it.

I also changed up the ConnectionList, which I previously added to the SocketHandler base class, but I think that this is too restrictive, as there might be the need for other datastructures (like a map mapping an identifier to the Object), so this is something the SocketHandler now has to manage manually (see BroadcastServer as an example).
Title: Re: Websockets Server/Client Implementation
Post by: senglit on September 14, 2022, 04:40:05 am
hi.

I have a websockets server(something like the demo "broacast server") started as a thread in my app. In the main thread I want to detect if the ws server works properly. If something wrong, I'd like to destroy the old ws server thread and start a new one.

In other job thread, I just do it by "feedding dog", to inc a counter defined as global.

How to do it with ws server? When the ws server thread is started up and socket.start is called the ws thread lost the control of socket and handler. I don't know where to add the "feed dog" clause.
TinyPortal © 2005-2018