Giter Site home page Giter Site logo

Comments (16)

ihmpartners avatar ihmpartners commented on May 11, 2024

a bit of a development ......

If the order of the ws_socket calls to create the sockets is changed then the last one in the list becomes the set that services events.

int main(void)
{
	struct ws_server data_srv;
	data_srv.host = "0.0.0.0";
	data_srv.port 				 = 6060;
	data_srv.thread_loop   = 1;
  data_srv.timeout_ms    = 10000,
	data_srv.evs.onopen    = &onDataOpen;
	data_srv.evs.onclose   = &onDataClose;
	data_srv.evs.onmessage = &onDataMessage;


	
  ws_socket(&(struct ws_server){
    .host					 = "0.0.0.0",
    .port 				 = 6061,
    .thread_loop   = 1,
    .timeout_ms    = 10000,
 		.evs.onopen    = &onGraphOpen,
		.evs.onclose   = &onGraphClose,
		.evs.onmessage = &onGraphMessage
		});    
		
		
  ws_socket(&(struct ws_server){
    .host				 	 = "0.0.0.0",
    .port        	 = 6062,
    .thread_loop 	 = 1,
    .timeout_ms  	 = 10000,
		.evs.onopen    = &onAlertsOpen,
		.evs.onclose   = &onAlertsClose,
		.evs.onmessage = &onAlertMessage
		});		
		
  ws_socket(&data_srv);  	
  

and all events are serviced by the Data events.

from wsserver.

ihmpartners avatar ihmpartners commented on May 11, 2024

I think I need some threads .........

from wsserver.

Theldus avatar Theldus commented on May 11, 2024

Hi @ihmpartners,
This is indeed a bug that I had never noticed, thank you very much for reporting it.

Commit 2169643 should fix this. Please let me know if this works for you.


Edit:
Tip: You don't need to do an infinite loop to keep the main thread of the program blocking, you can just set .thread_loop = 0 in the last call to ws_socket(), as in:

...

ws_socket(&(struct ws_server){
    .host = "0.0.0.0",
    .port = 6060,
    .thread_loop   = 1,
    .timeout_ms    = 10000,
    .evs.onopen    = &onDataOpen,
    .evs.onclose   = &onDataClose,
    .evs.onmessage = &onDataMessage
});
ws_socket(&(struct ws_server){
    .host = "0.0.0.0",
    .port = 6061,
    .thread_loop = 1,
    .timeout_ms  = 10000,
    .evs.onopen    = &onGraphOpen,
    .evs.onclose   = &onGraphClose,
    .evs.onmessage = &onGraphMessage
});
ws_socket(&(struct ws_server){
    .host = "0.0.0.0",
    .port = 6062,
    .thread_loop = 0, /* <-------------------- here. */
    .timeout_ms  = 10000,
    .evs.onopen    = &onAlertsOpen,
    .evs.onclose   = &onAlertsClose,
    .evs.onmessage = &onAlertMessage
});

so you do not waste CPU cycles 😉.

from wsserver.

ihmpartners avatar ihmpartners commented on May 11, 2024

Hi.

Yes I am adding some more code after the socket instantiations so for the moment ...... the loop code.

I am doing some testing but currently I appear to still have a problem.

1 - Open my 3 servers 6060,6061 and 6062 and
2 - Open the clients from a single web page. once each connection is established a simple text message is passed to the each socket which responds with a message

The following shows how the server responds. ( Chrome Web dignostics )

Subscribe to Data 6060
ws_sockets.js:23 Data Socket RECV: {"test": "D channel 6060"}
setInstGraph.js:54 Subscribe to Graph 6061
ws_sockets.js:41 Graph Socket RECV: {"test": "D channel 6060"}
ws_sockets.js:41 Graph Socket RECV: {"test": "G channel 6061"}
setInstGraph.js:60 Subscribe to Alerts 6062
ws_sockets.js:41 Graph Socket RECV: {"test": "G channel 6061"}
(2)ws_sockets.js:59 Alert Socket RECV: {"test": "G channel 6061"}
(3)ws_sockets.js:23 Data Socket RECV: {"test": "G channel 6061"}
ws_sockets.js:41 Graph Socket RECV: {"test": "G channel 6061"}

subscribe to .... is sent from the browser
ws_sockets.js nn is each service routine showing the data it receives. so in this case. ( so far so good )
6060 opened, server on 6060 responds to 6060.
(2) 6061 opened, server on 6060 responds to 6060 and then server on 6061 responds to 6061 ( why is 6060 in here and response received twice )
(3) 6062 opened, server on 6061 responds to 6061 6062 and then to 6060 ( received 3 times - some of this tranche may be from the first or second subscribe as opening 2 sockets also results in mixed messages )
a last message is sent to the 6061 socket from the server service routine on 6061

as you can see it looks as if as stack of calls are being repeated. I'll have a look at the source but I am snowed under with other work atm! )

it looks as if a stack of calls are being itterated through from the bottom rather than from some index point ..... you get my meaning ....

Ahh .... to add to the problem. separate browser instances do not open unique sockets, refreshing browser 1 results in identical data being transmitted to browser 2. ( this doesn't happen with the last build if multiple instances of the process are started, each sericing a single port )

from wsserver.

Theldus avatar Theldus commented on May 11, 2024

Hi @ihmpartners,
This is weird, I can't reproduce your issue here.... connecting to the example html (examples/echo/echo.html) on three different ports, messages are only sent and received to that port, messages are not mixed .

Could you provide me a minimal reproducible example that shows this problem? (html + .c)

from wsserver.

ihmpartners avatar ihmpartners commented on May 11, 2024

from wsserver.

ihmpartners avatar ihmpartners commented on May 11, 2024

from wsserver.

Theldus avatar Theldus commented on May 11, 2024

Hi @ihmpartners,
(Sorry for the delay; I've been quite busy in the last few days.)

Your YouTube video is set to private, and your message doesn't have any attachments. If you could look into this, I would appreciate it.

from wsserver.

Theldus avatar Theldus commented on May 11, 2024

@ihmpartners
Issue #86 may be related to yours and I've pushed a fix for it.
Could you check if this fix works for you too?

from wsserver.

ihmpartners avatar ihmpartners commented on May 11, 2024

from wsserver.

Theldus avatar Theldus commented on May 11, 2024

@ihmpartners
I've now noticed that your video is publicly available; thank you for the detailed demonstration. I finally understand what's going on.

In commit cb2c3f8 (PR #45), a code refactoring was performed, and the signature of the ws_sendframe() function was simplified from:

int ws_sendframe(int fd, const char *msg, uint64_t size, bool broadcast, int type);

to:

int ws_sendframe(ws_cli_conn_t *client, const char *msg, uint64_t size, int type);

Additionally, the broadcast functionality is now signaled when 'client' is NULL.

The issue is that, with 'client' being NULL, it becomes impossible to determine which port to send the broadcast message to. As a result, it is sent to all connected clients, regardless of their associated ports. This is why you were receiving mixed messages.

Unfortunately, this is not a bug, but at the same time, it is unexpected behavior for the user. Perhaps I should reintroduce the 'broadcast' parameter in the ws_sendframe()/ws_sendframe_txt()/ws_sendframe_bin() routines. What do you think? Any suggestions?

The only issue is that it might become a bit confusing to use:

if: client != true && broadcast != true -> ??? (error?)
if: client != true && broadcast == true -> broadcast to all clients
if: client == true && broadcast != true -> message to the specified client
if: client == true && broadcast == true -> broadcast to the client's port

edit:
The 'broadcast' parameter could be an integer instead of a boolean, with the following values:

NO_BROADCAST   (0): No broadcast.
ALL_BROADCAST  (1): Broadcast to all clients (regardless of the port).
PORT_BROADCAST (2): Broadcast to all clients on the same port as 'client'.

In this way, the 'client' parameter becomes mandatory rather than optional, but I believe it simplifies the API. What are your thoughts on this?

edit2:
The proposal above requires users to have prior knowledge of a client associated with the port they want to broadcast to, which may not be ideal...

Perhaps, then, introducing separate methods for broadcasting?

ws_sendframe()
ws_sendframe_txt()
ws_sendframe_bin()

ws_sendframe_port(6060, ...)
ws_sendframe_txt_port(6060, ...)
ws_sendframe_bin_port(6060, ...)

The first three methods maintain their current behavior: if NULL, broadcast to all. The last three methods allow the selection of a port without specifying a particular client.

Or some variation of this...

edit3:
Or maybe a general broadcast (ignoring ports) doesn't make sense...

from wsserver.

ihmpartners avatar ihmpartners commented on May 11, 2024

from wsserver.

Theldus avatar Theldus commented on May 11, 2024

Hi @ihmpartners,
Commit fbc1547 changes the semantics of the ws_sendframe*() functions and introduces three new functions: ws_sendframe_bcast(), ws_sendframe_txt_bcast(), and ws_sendframe_bin_bcast().

These new functions are intended for broadcasting and take the port as a parameter instead of the client, as follows:

ws_sendframe_bcast(6062, msg, size, type);
ws_sendframe_txt_bcast(6062, msg);
ws_sendframe_bin_bcast(6062, msg, size);

The old functions still exist, but they no longer send broadcast messages, and passing a NULL client to them is now considered an error!

Please let me know if these changes works for you, and thank you very much for your persistence in helping me resolve this issue. I greatly appreciate it.

from wsserver.

ihmpartners avatar ihmpartners commented on May 11, 2024

from wsserver.

Theldus avatar Theldus commented on May 11, 2024

Hi @ihmpartners,
Glad to hear it works well for you now, I'll close the issue, but feel free to open another one for any issues you have.

from wsserver.

ihmpartners avatar ihmpartners commented on May 11, 2024

from wsserver.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.