This question is with regards to my project on federated learning using the pysyft library, but those with the knowledge of websockets can help too since pysyft uses websockets for the server and client interaction.
To start off, i have an issue regarding server and client interaction. I have created a dashboard to launch a pysyft server and a pysyft client which connects to the aforementioned server. However, i have a scenario where i want to have the client disconnect from the server from time to time (manual disconnection) so as to perform changes in model parameters.
My solution was to perform a close() on the pysyft websocketClientWorker which calls the shutdown() function on the websocket object. Doing which, i presume, will close the connection between the client and the server. After whatever changes to the model parameters have been done. I will recreate the pysyft websocketClientWorker object again and perform the model training all over again. However, i am faced with the issue of : websocket._exceptions.WebSocketConnectionClosedException: socket is already closed. This exception is being thrown (despite the successful connection to the server) during the iteration of the dataloader.
Perhaps there's a better way to go about this scenario, or am i missing certain fundamental understanding of websockets. Any help will be appreciated. Thank you :)
I managed to find the solution to my question after days of thorough inspection of the pysyft library. Turns out there is no issue with the Websocket connection and re-connection. Apparently, the superclass of websocketclient (baseworker) contains a worker registry which caches the websocketclient objects when the auto_add variable is set to True. This registry is indexed by the websocketclient ID and thus, recreation of the websocketclient object will not get replaced in the registry if the ID is the same. Therefore, this explains the 'socket is already closed' issue since it's referencing to the previous websocketclient connection that I have closed. The solution was to simply call the remove_worker_from_local_worker_registry() method on the websocketclient object before closing its connection.
Related
In a Webserver for basic static website non-blocking event-driven, I don't understand the mechanics I should implement for a "new client".
When a browser connects to my socket, I get the clientfd from accept and answer with a HTTP response, but when the browser is reloaded, should it create a new connection and answer, or should it reuse the same connection and just send the new response?
I use poll to handle multiple fds, but when I reload the page its the same connection (for me this makes sense) but then I open a new tab, and it's still the same connection (It only does accept once). I'm not finding any documentation on this, and I don't have a way to test with multiple client's if it reuses the same one every time.
You can't reuse a connection from another client, new connections must always be accepted as new connections. It doesn't matter what kind of server application you're writing.
However, if the client passes the header Connection: keep-alive you should not close the connection once the response is finished, but keep the connection open for future requests from the same client.
I hope i understand correctly,
but anyway, What i personally do is create a map of sockets, each socket is a client.
Every time a socket disconnects, it's being removed from that map... and so on...
Whether to use a new connection is the browser's choice. You don't get much of a choice.
However, you can tell the browser that you don't allow it to reuse a connection, if you send Connection: close in the response. In this case, the browser is forced to open a new connection for the next request. This is the only control you have.
If you want to test several connections at the same time, you could open several different browsers, or you could use a different program, such as some HTTP load testing tool (there are many). You could also send it a web page with many images; browsers should try to download all the images using several connections at the same time.
A web server doesn't create clients. A web server has clients -- new clients trying to connect, and existing clients communicating on the sockets that it has already opened.
To handle new clients, a web server should pretty much be calling accept all the time, unless it's already handling the maximum number of clients that it's configured to handle.
As soon as you get a new connection from accept, hand it off to other threads to process and call accept again.
How can I get time for which the client is connected to a socket?
There is no such feature.
I'd suggest creating #OnOpen method, which will save the time to current instance (Endpoints are by default WebSocket Session scoped) and work with that value.
Feel free to file an enhancement against Tyrus.
I'm using org.eclipse.jetty.websocketclient and I want to open multiple web sockets to different URLs.
I'm working with Java.
How do I need to do that?
I want to open the web sockets in multiple threads.
1. Do I need to create websocketclient for each connection?
2. Can I use any websocketclient factory? Is there any?
3. Do I need to open only one websocketclient, keep it opened and open somehow web sockets with it?
4. What is wrong with creating multiple websocket clients?
This answer talks about Jetty 9 WebSockets.
you have 1 WebSocketClient, think of it as a Browser, with each call to connect() establishing a new connection.
Each call to connect() should have a new WebSocket instance, each instance will be managed by the WebSocketClient's Executor causing in essence each websocket instance to be on its own thread.
Followup Answers
Ideally, have only 1 WebSocketClient, and start it only once. leave it started for the time period where you have active websocket connections.
Stop the WebSocketClient when there are no more connections.
Generally speaking, avoid reusing objects for multiple requests, unless you know what you are doing. Example: the ClientUpgradeRequest and URI, are associated with the WebSocket Session, which if reused across multiple connections, will have a state change on close of the first connection, making the data invalid for the other connections, then there is also the Garbage collection references that make cleaning up the old connections difficult until all connections are closed.
You can call connect() concurrently, go for it. Each connection attempt is processed based on the Executor behavior (eg: if you have a single threaded Executor, then only 1 connect occurs at a time)
Creating a new WebSocketClient for every connect is excessively wasteful of resources. It would be like starting an entire WebServer for each incoming request. A WebSocketClient manages the selectors, threading, session tracking, etc. I realize where you are coming from, with older http client libraries having this behavior, but even those http clients are updating themselves to this new browser-ish model thanks to spdy and http/2.
I'm starting with Websockets and I have a problem.
I have a sails.js application that uses sockets to update the client side.
On the client side it makes an API call using socket.get("/api/v1/actor...") to bring all the items of the database. When I see what the WebSocket's traffic on the Chrome console:
As you can see, the connection has been established and the API call has been correctly done through the socket.
The problem is, there is no answer from the server, not even an error.
If I make the same API call using ajax, I get response, but it doesn't work using WebSockets.
Any idea what might be producing this behavior?
EDIT: I add here the code here that processes the request and this one here that sends the request, but the problem is that it never execute this code. I think we we are closer to the find the cause, since we think it has to do with a network problem. We figured there is an F5 reverse-proxy which is not properly set up to handle websockets
The answer didn't make any sense now that I've seen the code that's why I've edited it. I only answered because I could't comment on your question and ask you for the code.
Your calling code seems correct and the server side of things the process of response should be handled automatically by the framework, you only need to return some JSON in the controller method.
I instantiated a copy of the server (just changed the adapters to run it locally) and the server replied to the web socket requests (although I only tested the route '/index').
Normally when the problems are caused by a reverse proxy the socket simply refuses to connect and you can't even send data to server. Does the property "socket.socket.connected" returns true?
The best way to test is to write a small node application with socket.io client and test it in the same machine that the application server is running, then you can exclude network problems.
I am trying to execute a SOAP message for an SPML searchRequest iterator. My endpoint is using the Quest SPML Provider tool which sits on top of IIS.
The problem is, I execute the search, it returns the results and an iterator ID. You take this iterator ID and make another request (this time an IteratorRequest) and the web service will return the next set of items.
When this is done through either the UI provided with the software, or through SoapUI, I have no problems, but when implementing through Spring, I get an invalid ID.
After some digging, I found this https://support.quest.com/SolutionDetail.aspx?id=SOL76284 which is stating that when a connection, or session is lost to the endpoint, the iterator will be made invalid.
My question is, is there a way to force a WebServiceTemplate.marshalSendAndReceive to keep a connection alive until I'm done iterating through the results? Or am I offbase, and need to pursue a different avenue.
Thanks a bunch!
The messageSender is what is used by the WebServiceTemplate to send the payload over protocol of choice. If it is HTTP then you can configure it to use HttpComponentsMessageSender that uses HttpClient which supports persistent HTTP connections (keep-alive).
NOTE
HTTP/1.1 has connection keep-alive but the server can decide to close it after a number of requests or does not support keep-alive.
Even JDK 6 related classes support keep-alive but you can enable pooling with HttpClient