Coding4ever’s Blog

Just coding… coding… and coding… because coding should be fun :)

Aplikasi Antrian

| Comments

Aplikasi ini merupakan pengembangan dari sample aplikasi yg sudah pernah saya bahas pada postingan sebelumnya, aplikasi ini terdiri dari 2 project yaitu :

  1. Aplikasi server memanfaatkan array winsock karena akan menghandle minimal 1 koneksi

  2. Untuk aplikasi klien cukup menggunakan winsock standar (non array).

Sekarang akan kita bahas cara pembuatannya.

Aplikasi server

Aplikasi server menggunakan winsock yg dijadikan array karena akan menerima lebih dari 1 koneksi, untuk menjadikan sebuah winsock menjadi array cukup dengan mengeset properties index = 0

Selain itu agar sebuah winsock bisa menerima koneksi yg masuk, maka winsocknya harus dalam mode “Listen”, untuk keperluan ini kita akan menyiapkan sebuah fungsi misal dengan nama startListening

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Private Function startListening(ByVal localPort As Long) As Boolean
    On Error GoTo errHandle

    If localPort > 0 Then
        'If the socket is already listening, and it's listening on the same port, don't bother restarting it.
        If (wckServer(0).State <> sckListening) Or (wckServer(0).localPort <> localPort) Then
            With wckServer(0)
                Call .Close
                .localPort = localPort
                Call .Listen
            End With
        End If

        'Return true, since the server is now listening for clients.
        startListening = True
   End If

   Exit Function
errHandle:
   startListening = False
End Function

Selanjutnya tinggal kita panggil pada event Form_Load

1
2
3
4
5
6
7
8
9
Private Sub Form_Load()
    '1234 adalah port yg digunakan untuk komunikasi
    'antara server dan klien, nilainya bisa disesuaikan
    If startListening(1234) Then
        MsgBox "Status Server ON"
    Else
        MsgBox "Status Server OFF"
    End If
End Sub

Selain itu ada beberapa kode yang harus kita lengkapi pada event2x yg dimiliki oleh winsock yaitu event Close, ConnectionRequest, DataArrival dan Error

1
2
3
4
Private Sub wckServer_Close(Index As Integer)
    ' Close the socket and raise the event to the parent.
    Call wckServer(Index).Close
End Sub
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Private Sub wckServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    Dim i          As Long
    Dim j          As Long
    Dim blnLoaded  As Boolean

    On Error GoTo errHandle

    ' We shouldn't get ConnectionRequests on any other socket than the listener
    ' (index 0), but check anyway. Also check that we're not going to exceed
    ' the MaxClients property.
    If (Index = 0) Then
        ' Check to see if we've got any sockets that are free.
        For i = 1 To wckServer.UBound
            If (wckServer(i).State = sckClosed) Then
                j = i
                Exit For
            End If
        Next i

        ' If we don't have any free sockets, load another on the array.
        If (j = 0) Then
            blnLoaded = True
            Call Load(wckServer(wckServer.UBound + 1))
            j = wckServer.Count - 1
        End If

        ' With the selected socket, reset it and accept the new connection.
        With wckServer(j)
            Call .Close
            Call .Accept(requestID)
        End With

    End If

    Exit Sub
    '
errHandle:
    ' Close the Winsock that caused the error.
    Call wckServer(0).Close
End Sub

Event ConnectionRequest berfungsi untuk memfilter koneksi yg masuk, jika ada koneksi yg masuk akan dilakukan pengecekan terlebih dulu apakah ada winsock yg idle (ngangur) jika ada maka koneksi tersebut akan langsung dihandle oleh winsock yg idle tadi, jika tidak maka akan diload terlebih dulu winsock yg baru kemudian langsung menghandle koneksi yg baru masuk tadi.

Teknik ini merupakah salah satu cara untuk melakukan optimasi program jangan sampai aplikasi server meload secara terus menerus objek winsock yg baru untuk setiap koneksi yg masuk.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Private Sub wckServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    Dim cmd     As String

    On Error GoTo errHandle

    ' Grab the data from the specified Winsock object, and pass it to the parent.
    Call wckServer(Index).GetData(cmd)

    Select Case cmd
        Case "get_no_antrian"
            Call send(Index, CStr(noAntrian))

            lblNoAntrian.Caption = noAntrian
            noAntrian = noAntrian + 1 ' naikkan counter nomor antrian

        Case Else
            Call send(Index, "perintah tidak dikenal")
    End Select

    Exit Sub
errHandle:
   Call wckServer(Index).Close
End Sub

Event DataArrival berfungsi untuk memproses data yg masuk, untuk kasus aplikasi antrian ini data yang paling valid hanya berupa string “get_no_antrian”, jika datanya valid akan langsung dikirimkan nomor antrian terakhir ke klien yg mengirimkan string “get_no_antrian” dg memanggil prosedur send.

1
2
3
4
5
6
7
Private Sub send(ByVal lngIndex As Long, ByVal strData As String)
    If (wckServer(lngIndex).State = sckConnected) Then
        Call wckServer(lngIndex).SendData(strData): DoEvents
    Else
        Exit Sub
    End If
End Sub
1
2
3
Private Sub wckServer_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
    Call wckServer(Index).Close
End Sub

Untuk aplikasi server sy rasa sudah cukup akan kita lanjutkan dg aplikasi klien.

Aplikasi Klien

Untuk aplikasi klien lebih sederhana lagi, yg kita butuhkan cukup sebuah fungsi untuk melakukan koneksi ke server

1
Private Const conTunggu As Long = 100000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Private Function isConnected(ByVal ipServer As String, ByVal port As Long) As Boolean
    Static i As Long

    On Error Resume Next

    If myClient.State <> sckClosed Then myClient.Close ' close existing connection
    myClient.RemoteHost = ipServer
    myClient.RemotePort = port
    myClient.Connect

    With myClient
        Do Until .State = sckConnected
            DoEvents
            i = i + 1
            If i >= conTunggu Then
                i = 0
                Exit Function
            End If
        Loop
    End With

    isConnected = myClient.State = sckConnected
End Function

Contoh pemanggilan fungsi diatas seperti berikut :

1
2
3
4
5
6
7
8
9
10
11
12
Private Sub cmdAmbilNoAntrian_Click()
    Dim ipServer    As String
    Dim cmd         As String

    ipServer = "127.0.0.1"
    cmd = "get_no_antrian"

    ' 1234 ada port yg menyesuaikan port yg ada di server
    If isConnected(ipServer, 1234) Then
        myClient.SendData cmd
    End If
End Sub

Untuk mengetahui data yang dikirim balik oleh server kita bisa memanfaatkan event DataArrival yg dimiliki oleh objek winsock

1
2
3
4
5
6
7
8
Private Sub myClient_DataArrival(ByVal bytesTotal As Long)
    Dim noAntrian As String

    On Error Resume Next

    myClient.GetData noAntrian
    lblNoAntrian.Caption = noAntrian
End Sub

Selesai :)

Aplikasi diatas belum menggunakan database sama sekali, sehingga jika aplikasi server ditutup maka counter nomor antrian akan dimulai dari 1 lagi, dan sy berharap tidak ada pertanyaan bagaimana menyimpan counter nomor antriannya ke database atw bagaimana cara menampilkan nomor atrian terakhir klo servernya error :D.

Selamat MENCOBA :)

Comments