I'm trying to understand what RPC binding handle is (DCE1.1 Remote procedure call).
Does the binding handle is valid as long as the connection between the RPC client and server is active?
What happens when the connection is lost (unexpectedly)? Does the client needs to bind again, receiving a new binding handle?
Or does the handle can be used by the RPC client on multiple connections to the server?
Thanks!
Related
I have some tasks to do for certain commands I receive and would like to keep the client from (read-)timeouts by sending some data while doing the task.
Does the AResponseInfo object offer anything to accomplish this?
I currently use the ContentText property, but it sends the data (as it seems) at the end of the event handler.
By default, TIdHTTPServer sends a response when the OnCommand... event handler exits. However, it is possible to send a response sooner, by either:
calling the AResponseInfo.WriteHeader() and AResponseInfo.WriteContent() methods after populating the AResponseInfo properties as needed.
writing directly to the TCP socket, and then setting the AResponseInfo.HeaderHasBeenWritten property to true so TIdHTTPServer does not try to send its own response.
Note: once you send a response to the client, the client is free to send new requests using the same TCP connection (if HTTP keep-alives are used), but you will be holding up the connection from processing those requests until you exit the OnCommand... event handler.
If you have long processing to do, it is generally better to send a normal response back to the client as soon as possible, for instance with a 102 Processing response, exit the OnCommand... event handler so the server regains control of the connection, do the actual processing in the background, and let the client query the status of the processing using subsequent requests as needed. You could assign a cookie or other type of server-generated ID to the processing, and then have the client send that cookie/ID back to the server to query the processing's status.
I would like to create Inter Machine Communication using INDY TCP Client and Server components. IdTCPServer has an event called OnExecute which is triggered when client wants something from server. I would like to create the same functionality, when SERVER sends request to the CLIENT which would have the same OnExecute event, just like it was working as server. Is it easily to achieve? I need it because I can connect to the peer only one-way (NAT)
IdTCPServer has an event called OnExecute which is triggered when client wants something from server.
That is not how the TIdTCPServer.OnExecute event works. It is called in a continuous loop for the lifetime of the connection, regardless of anything that the client or server do with the connection between the time it is connected and the time it is disconnected.
The typical usage of the event is to block the calling thread waiting for the client to send a packet, then reply with a packet, and then exit, letting the loop fire the event again so it can wait for the next client packet.
But this is not the only way the event can be used.
I would like to create the same functionality, when SERVER sends request to the CLIENT which would have the same OnExecute event, just like it was working as server. Is it easily to achieve?
TIdTCPClient does not implement that kind of logic natively. It merely provides a connection, but you have to write your own code to tell it when to read and write data over that connection.
For what you are asking, you will need to create your own worker thread, either by writing a TThread/TIdThread-derived class, or using the TIdThreadComponent component. When the client connects to the server, start the thread. When the client disconnects, stop the thread. Then your thread can do whatever you want with the connection, just like with the TIdTCPServer.OnExecute event.
Depending on the format of your commands/responses, you might be able to use TIdCmdTCPClient instead of TIdTCPClient. TIdCmdTCPClient runs its own thread internally, and its CommandHandlers collection parses inbound requests and generates outgoing responses. All you would have to do is populate the collection with TIdCommandHandler objects that define the parsing criteria for each request, and assign an OnCommand event handler to each one to react to each request that the server sends.
I am trying to use EventSource on the client side and
one the server side I am using HttpRequest.response
which returns an object of type HttpResponse.
I am using HttpResponse.write to write events back
to the client side but it seems that these events
are only actually written (i.e., flushed) when the
HttpResponse object is closed, which implies also
closing the client-server communication server.
This kind of defeats the purpose of using EventSource.
Am I doing something wrong?
What you want to be looking at if you want to keep the connection between client and server alive between requests is called WebSockets.
See this tutorial for examples: https://www.dartlang.org/docs/dart-up-and-running/contents/ch05.html
ive a sever running TIdTCPServer, and Client Using Web Browser (or any other software) to Communicate, i dunno the protocol, but what im trying to do is to Send The Data between the client and another Connection (Both Connected to the same TIdTCPServer) for example the data sent by the first client is transmitted to the second client, and the data sent by the second client is transmitted to the first client, like a proxy (i cant really use a proxy server since its just this one condition) and the TIdTCPServer should still be receiving other clients and processing their data.
i stumbled upon the first line of code, since TIdContext.Connection.Socket.ReadLn requires a Delimiter, and the Client's Protocol is unknown to the server.
any ideas?
thanks.
You can look at the source code for TIdMappedPortTCP and TIdHTTPProxyServer to see how they pass arbitrary data between connections in both directions. Both components use TIdSocketList.SelectReadList() to detect when either connection has data to read. TIdMappedPortTCP then uses TIdBuffer.ExtractToBytes() and TIdIOHandler.Write(TIdBytes), whereas TIdHTTPProxyServer uses TIdTCPStream and TIdBuffer.ExtractToStream() instead.
I need to program a stateless server to execute remote methods. The client uses REST with a JSON parameter to pass the method name and its parameters. After servicing the result the session is closed. I have to use Indy10, TCP/IP as protocol, and therefore look at using IdHTTPServer.
Large result sets are chunked by Indy10 and sent to the client in parts.
My problem now is:
The methods on the server provide progress information if they take longer to produce the results. These are short messages. How can I write back to the client?
So far I have used writeflush on the server, but the client waited for the request to end before handing back the full resultset, including the progress information. What can I do to display/process such progress information on the client and yet keep the connection open to receive further data on the same request?
On the client side instead of the regular HTTP client component TIdHTTP you can instead use Indy class TIdTCPClientCustom in unit IdTCPClient to send the request and process the response.
This class gives total control over the processing of the server responses. I used the TIdTelnet class as a starting point to implement a client for a message broker messaging protocol, and found it stable and reliable for both text and binary data.
In the receiving thread, the incoming data can be read up to delimiters and parsed into chunks (for the progress information) and immediately processed.