B4J Question Same socket for 2 AsyncStreams

PatrikCavina

Active Member
Licensed User
I have this situation,
my device only works on low-level TCP.
This device uses 2 sockets:
  • The first socket is used to receive and return the command acknowledge.
  • The second socket is used only to return device status information.
The second socket is connected by the device only after the device receives the "CONNECT" command on the first socket.

I would like to create a class where only after both sockets are connected the "_SocketsReady" event goes up with Socket1 and Socket2 as parameters.

My problem is that to do this I would have to initialize an AsyncStream where the _NewConnection event of the first socket rise and reuse the same socket on a new asyncStream of target module.
Is it a proper socket management?

I hope my problem will be clearer in the example below:

MyServer Class:
B4X:
#Event: SocketsReady (Socket1 As Socket, Socket2 As Socket)
Sub Class_Globals
    Private cBack As Object
    Private eName As String
    
    Private srv1 As ServerSocket
    Private srv2 As ServerSocket
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize (Port As Int, EventName As String, CallBack As Object)
    eName = EventName
    cBack = CallBack
    srv1.Initialize(Port, "Srv1")
    srv2.Initialize(Port+1, "Srv2")
End Sub

Public Sub Start
    Do While True
        srv1.Listen
        srv2.Listen
        Wait For Srv1_NewConnection (Successful As Boolean, cmdSocket As Socket)
        If Successful Then
            
            Dim tmpStream As AsyncStreams '<---------------------------------------------------- TEMPORARY STREAM TO REQUEST THE CONNECTION TO THE SECOND SOCKET
            tmpStream.Initialize(cmdSocket.InputStream, cmdSocket.OutputStream, "tmpStream")
            tmpStream.Write("CONNECT".GetBytes("UTF-8")) '<------------------------------------- SEND CONNECT COMMAND
            Wait For tmpStream_NewData (Buffer() As Byte)
            Dim ack As String = BytesToString(Buffer, 0, Buffer.Length, "UTF-8") '<------------- ACKNOWLEDGE FROM FIRST SOCKET
            
            If ack.Contains("OK") Then
                Wait For Srv2_NewConnection (Successful As Boolean, stateSocket As Socket) '<--- WAIT FOR THE CONNECTION OF THE SECOND SOCKET
                If Successful Then
                    CallSub3(cBack, eName&"_SocketsReady", cmdSocket, stateSocket) '<----------- PASS TO TARGET MODULE 2 SOCKETS WILL USED FROM ASYNCSTREAM OF TARGET MODULE
                End If
            End If
            
        End If
    Loop
End Sub
Main:
B4X:
Sub Process_Globals
    Private server As MyServer
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    server.Initialize(4662, "MyServer", Me)
    server.Start
End Sub

Sub MyServer_SocketsReady (cmdSocket As Socket, stateSocket As Socket)
    
     Dim device As ClientDevice'<--------ClientDevice Initialize AsyncStream with cmdSocket
     device.Initialize (cmdSocket, stateSocket)
     ...
     ...
    
End Sub
 

PatrikCavina

Active Member
Licensed User
But if i pass the "temp" asyncstreams to the class, events of passed asyncstreams will rise on MyServer class and not in the ClientDevice.
Or there is a way to redirect events?
 

PatrikCavina

Active Member
Licensed User
In this case i need to initialize the client in server class and store them in a server variable like a map where key is the asyncstream and value is the client class.
Is it correct?
 
Last edited:

PatrikCavina

Active Member
Licensed User
I think i'll create 1 class for each sockets.
Each class will take as init parameter the socket and it will create astream object within it.
This two classes will be inside Client class, where the first astream will initialize immediatly after the first socket connection.

The client will send connect command on the first astream, it will wait the connection of the second socket and then it will set the second astream

Clients will stored in a list
 
Top