Results 1 to 7 of 7

Thread: [RESOLVED] winsock multi-user chat: Change index value of control at runtime

  1. #1

    Thread Starter
    Member
    Join Date
    Apr 2010
    Location
    Gold Coast, Australia
    Posts
    43

    Resolved [RESOLVED] winsock multi-user chat: Change index value of control at runtime

    The major problem that i have been stuck with is when a client disconnects from the server, the connection is closed and the control is unloaded.

    when i try to send new information to other clients i am using a "For next" loop, however when i do this, it will error because one of the connections is not connected at the time.

    i searched on google to see if i could change the index property of a control at runtime so that i can fix the control array so that there is no gaps, but after looking i don't think you can change that value..

    what would be the easiest way to do this? to handle when a user leaves the chat and so that the server can still send messages to all connected clients.

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: winsock multi-user chat: Change index value of control at runtime

    Welcome to VBForums

    One solution is rather than using a For loop, use a For-Each, eg:
    Code:
    Dim objWinsock as Winsock
      For Each objWinsock In Winsock1  'change to the name of your array
        'use objWinsock here, rather than Winsock1(x)
      Next objWinsock

  3. #3
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: winsock multi-user chat: Change index value of control at runtime

    Actually it is better not to unload Winsock controls.

    The simple approach is for a new connection request to scan the existing control array for an open slot (control that has State = sckClosed) and then use that. Only if you run out of controls would you Load a new one at the end and use it.


    For a long-running server you might even get trickier. Every time a user connects do this scan-and-add as described. However if you didn't Load a new instance do a backward scan of the control array. If you find at least 3 (or 5, etc.) unused slots at the end Unload them to free resources.

    Note that unless you are using the VB6 SP6 version of the Winsock control there is a memory leak when you unload them! This was once a serious problem for long-running servers, but it was fixed somewhere from SP5 to SP6. Always use the SP6 control. It is probably the last version we'll ever see and a very large number of improvements were made over the years, most of them applying to use in servers.

  4. #4

    Thread Starter
    Member
    Join Date
    Apr 2010
    Location
    Gold Coast, Australia
    Posts
    43

    Re: winsock multi-user chat: Change index value of control at runtime

    Thanks for the welcome and thanks so much for the quick reply.

    i'm pretty sure that will fix my problem but at the moment i am using a variable to determine how many connections i have so when a user connects they will connect to Winsock(Variable) rather than any connection available

    is there a way of making a new control with an index closest to 1 as possible that doesn't already have a connection?

    Edit: dilettante answered my question thanks very much, i was just late to reply this post hehe.. I will now search the forums on how to search for an unused loaded winsock, thank you very much
    Last edited by koushi; Apr 25th, 2010 at 09:13 AM.

  5. #5

    Thread Starter
    Member
    Join Date
    Apr 2010
    Location
    Gold Coast, Australia
    Posts
    43

    Re: winsock multi-user chat: Change index value of control at runtime

    Ok so i know this code is a bit messy.. but it works for me, it now just error traps 340 (which is saying a control doesn't exist) so therefore it creates one otherwise it loops through the other connections and if it finds one with a state not connected, it accepts the requestID to that connection.

    Code:
    Private Sub sockUser_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    Dim Attempt As Integer
    Attempt = 1
    
    On Error GoTo t
    
    k:
        If sockUser(Attempt).State = sckConnected Then
            Attempt = Attempt + 1
            GoTo k
        Else
            sockUser(Attempt).Accept requestID
            UserCounter = UserCounter + 1
            Exit Sub
        End If
    
    t:
        If Err.Number = 340 Then
            Load sockUser(Attempt)
            sockUser(Attempt).Accept requestID
            UserCounter = UserCounter + 1
            Exit Sub
        End If
    
    End Sub

  6. #6
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: [RESOLVED] winsock multi-user chat: Change index value of control at runtime

    Here is a tidied version of that, using the method shown in the FAQ article How do I detect if an index exists in a control array?:
    Code:
    Private Sub sockUser_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    Dim Attempt As Integer
    
      For Attempt = 1 To sockUser.UBound
        If VarType(sockUser(Attempt)) = vbObject Then  'check if array index is not in use
            Load sockUser(Attempt)
        End If
        If sockUser(Attempt).State <> sckConnected Then
            sockUser(Attempt).Accept requestID
            UserCounter = UserCounter + 1
            Exit Sub
        End If
      Next Attempt
    
    End Sub
    You should ideally add an error handler to this to deal with any unexpected errors somehow.

  7. #7

    Thread Starter
    Member
    Join Date
    Apr 2010
    Location
    Gold Coast, Australia
    Posts
    43

    Re: [RESOLVED] winsock multi-user chat: Change index value of control at runtime

    Thanks very much Si, i recently logged on and checked through my old posts to find this.

    I used your code, thanks very much, but there were a few things wrong with it that i had to fix.

    First of all: For Attempt = 1 to sockUser.Ubound is the same as For Attempt = 1 to 0 which does not start the loop.

    Second For Attempt = 0 to sockUser.UBound + 1 does not work as when i try sockUser(0).Accept request ID it comes up with an Error "Invalid operation at current state".

    So I fixed that issue by avoiding index 0 completely, so now my code is:
    For Attempt = 1 to sockUser.Ubound + 1


    ** Also if you just had For Attempt = 0 to sockUser.UBound the code would not get anywhere, as it will just keep trying to requestID on index of 0 and would not create any new winsock objects.


    This is what my code now looks like and works perfectly:

    Code:
        For i = 1 To sockUser.UBound + 1
            If VarType(sockUser(i)) = vbObject Then
                Load sockUser(i)
                sockUser(i).Accept requestID
                Exit Sub
            ElseIf sockUser(i).State <> sckConnected Then
                sockUser(i).Accept requestID
                Exit Sub
            End If
        Next i
    ** Take note that VarType() = vbObject is the same as VarType "is not the same as" vbObject. That's really confusing :S
    Last edited by koushi; Apr 10th, 2011 at 04:20 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width