Multiple asynchronous HTTPSecureSocket

I need to make several simultaneous calls asynchronously with HTTPSecureSocket in a desktop App.

Can I create HTTPSecureSocketobjects at runtime and then manage them?
Can I create an array of objects so as not to manually duplicate each one?
How can i handle receiving events for each object?
Well, how can I do it?

Thanks,
Gabriel

Yes

Yes, this is how you should do it!

You could create a subclass and add event handlers, or if you’ll need to do different things for each one you can AddHandler to the instance of each socket.

I very much so recommend using URLConnection and that you do not use HTTPSecureSocket.

This will vary depending on whether you create a subclass, add handlers, want to show progress, and how you need to scope everything. Try to build something and ask specific questions if you get stuck.

@Tim_Parnell I’m trying to do what you suggested.

I created a URLConnection class and inside I wanted to put a Timer to do some checks. I did like this:

self.TmrCode = new Timer
self.TmrCode.Period = 300
self.TmrCode.Mode = Timer.ModeMultiple
AddHandler TmrCode.Action, AddressOf self.TimerAction

But I get this error:
cUrlConnection.Inizialize, line 9
Type mismatch error. Expected delegate Delegate( Timer ), but got delegate Delegate( )
AddHandler TmrCode.Action, AddressOf self.TimerAction

TimerAction is a method in my class.

TimerAction needs to have a Timer in its declaration:

TimerAction (atimer as timer)

@TimStreater I did it thanks!

Now…
If I have two different asynchronous calls, how do i distinguish the answers if I only have one “ContentReceived” event?

I don’t know which one is called first and which one after, and even less do I know which answer of the two comes first.

You need to subclass the socket and make instances of that. You can add properties to the subclass and store an id in one which will tell the events which is which.

@TimStreater I have already subclassed the URLConnect where I have already entered several properties, methods and events that I need. But what I can’t figure out is how to add an ID to the call, and have the event “ContentReceived” return ID to me.

Set your id property when you instantiate the socket. That property will be directly available to your event handler.

But if the same object make two calls, the answer events have the same ID, right?

Are you expecting the contents received in the response to contain the ID or are you trying to set one yourself? Either way, what’s being recommended is that you add a property to your subclass cUrlConnection that contains that ID.

You can either parse your ContentsReceived and store the ID, or set it when you create the instance depending on your needs.

var oSock as new cUrlConnection
oSock.iMyID = 42

I have subclassed it with the property my ID property. But if I now make two calls with that subclass the ID will always be that in each answer. Right?
How I can get two different IDs, one per call? Have I to instantiate the subclass multiple times?

Yes and you should. In my experience, reusing a URLConnection instance leads to problems.

What is the ID property even for? Perhaps there’s something we can recommend to achieve your goals.

As per the post subject I need to make several simultaneous calls asynchronously. Now I use URLConnection bcs you recommended it to me.
I don’t know if there are 2 or 10 or more calls, and they can also be made simultaneously.
At this point I’m wondering how can I use URLConnect to make simultaneous calls?

If I could add an extra parameter in ContentReceived’s AddHandler and not exactly copy the event I might succeed.

As you mentioned in your original post, you need to create an array to store the running requests. You don’t need to assign them unique identifiers if you handle what the response from the server is.

// aroRequests() is an array of cUrlConnection as a property to stay in scope
// arsURLs() is an array full of your URLs you're requesting
// This is for illustration purposes only.

// Create a request for each url you have
for each sURL as String in arsURLs
  // New socket
  var oSock as new cUrlConnection
  
  // Append and retain the reference
  aroRequests.Add(oSock)

  // Send the request
  oSock.Send("METHOD", sURL)

next sURL

This code is an illustrative example only. I do API integrations all the time and can tell you it’s quite possible. The implementation varies a lot depending on your needs and the needs of the remote API.

I have no idea why you want to assign a unique identifier to each request, so I can’t tell you the best way to implement tracking it. I gave you a suggestion to build from. If you want a more specific answer you’ll have to enlighten us to why you think it’s necessary so we as a community can offer suggestions on how to best implement it.

In my experience implementing REST API solutions I have only ever needed to add an identifier filed to a subclass so that I could reconnect a response to a WebSession. I don’t understand what you’re trying to do, so I can’t help much more.

I do everything in threads. I store the socket subclass variable in a thread property, and a thread subclass variable in a socket property. That way any thread knows which socket it’s dealing with, and any socket knows which thread it’s dealing with. Thus cleanup is always possible and the event handlers know where to put the data etc. Having many threads running many sockets is thus not an issue.

Thanks @Tim_Parnell and thanks @TimStreater !!!
It took me a while but I managed it.

The problem arises from the fact that I have to call the same REST API with different parameters and I will get different results. In addition to this the calls are made with times not managed by me and can also be overlapping or perhaps delayed.
For example it could happen to have 3 simultaneous calls or almost, say A B and C. The answers could arrive in different qequence, for example B C and A.
So passing an identifier to know what the call was compared to the result is important to me.

Thanks to your suggestions I proceeded like this:

  1. I created a subclass of URLConnection called cUrlConn, like this:
    cUrlConn

  2. I’ve created a container class that contains all the methods, properties and events I need to manage that type of service. In this class I have inserted a property which is an array of cUrlConn, like: oConn() as cUrlConn.

  3. The container class has several methods that make calls to the same REST API but differently. Each of these methods creates a cUrlConn object and sets all properties, then is added to array oConn(), manage the AddHandler of the “ContentReceived” event, and finally executes the call.

Dim cUrl As New cUrlConn
cUrl.Method = sMethod
cUrl.ClearRequestHeaders
cUrl.JsonSent = sJson
cUrl.Side = "OVER"
cUrl.ClearRequestHeaders
cUrl.RequestHeader("Content-Type") = "application/json"
cUrl.SetRequestContent(sJson, "application/json")
Self.oConn.Append cUrl
cUrl.IdxCalled = Self.oConn.Ubound
AddHandler Self.oConn(Self.oConn.Ubound).ContentReceived, AddressOf Self.MultiContentReceived
cUrl.Send(CStr("POST"), CStr(sUrl + sMethod), Self.TimeOut )
  1. The “MultiContentReceived” method that manage the oConn() array event “ContentReceived” returns me the calling cUrlConn object. With that cUrlConn returned I can decide to do different things based on the properties of the object.

  2. At the end of the “MultiContentReceived” method I remove the handler, disconnect and cancel the object to free up memory (I don’t know if it is actually needed).

RemoveHandler Self.oConn(cUrlConn.IdxCalled).ContentReceived, AddressOf Self.MultiContentReceived
cUrlConn.Disconnect
cUrlConn = Nil
  1. To seriously free up memory, I completely delete the cUrlConn array. Because I have noticed that until I do it the memory is not free.
Redim Self.oConn(-1)

//or 

For i As Integer = Self.oConn.Ubound To 0 Step -1
  Self.oConn.Remove(i)
Next i

It seems that I have achieved the result I wanted. It seems that I have achieved the result I wanted. Sure there will be better methods, but that’s okay for now.

Thanks again.