socket write/read conflict?

Nicolas Cueto niconiko at gmail.com
Mon Mar 22 23:14:23 EDT 2010


Hello List,

I've made a quiz-type game where 2-6 students on client stacks buzz in
their answers to a server stack, all on a local network. The server
stack, as well as sending out the questions, informs live to all the
students/client-stacks about who buzzed in what.

I thought I had it working until we found a problem. If two out of six
students happen to buzz in an answer almost simultaneously (by
clicking a button on a game controller pad), as expected five of the
students will receive the server's message about who buzzed in first,
but one of those two students who buzzed at the same time won't.
Except for this simultaneity, all other server-to-client
communications work.

After trying to track this down for weeks, I'm posting here in hopes
of some list magic.

My guess, as the subject line reads, is that a client stack might be
writing to a socket at the same time that the server is trying to
write to that same socket. But, not understanding well how sockets
work, the problem may lie elsewhere. I think I've eliminated the
obvious types of mistakes, but...

So, I am including below the essence of what my server and script
stacks do. It is quite long, so apologies beforehand.

As always, the list's help in this is greatly appreciated.

Thank you.

-- Nicolas Cueto


##########################################################

S T A R T   O F   C L I E N T   S T A C K   R E L A T E D

################################
CLIENT CARD SCRIPT
################################

on opencard
   chatConnect
end open

local lChatSocket

on chatConnect
   open socket field "host" & ":1987|" & field "clientname" with
message "chatConnected"
end chatConnect

on chatConnected s
   put s into lChatSocket
   write field "clientname" & comma & field "studentID" & return to
socket lChatSocket
   read from socket s with message chatReceived
   ## Tell server that the student is ready to play, and then
   ## wait for student's choice of answer (by clicking on a
   ## game-controller button).
end chatConnected

on chatReceived s,data
   ##  "s" contains the host and port of the client,
   ## "data" contains the text sent by that client
   switch (line 1 of data)
      case "live choice feedback"
        ## A student/client on the network has buzzed in a choice/answer.
        ##
        ## The script does a long routine here, which includes
        ##
        ## << several "wait" and "wait with messages" >>
        ##
        ## Once done, the script asks server for next question.
        askServerForQuestion
        break
    end switch
    read from socket s with message chatReceived
end chatReceived

on askServerForQuestion
   chatMessage "ready for a question"
end askServerForQuestion

on chatMessage data
   ## Called by student clicking on an image/choice (script below).
   write data & comma & field "clientname" to socket lChatSocket
end chatMessage


############################################
GAME-CONTROLLER BUTTON & IMAGE SCRIPTS
############################################

on rawKeyUp theKey
   switch theKey
      case "49"
       put "ImgChoice1" into tImgChoice
      break
   end switch
   put the filename of image tImage into tHilitedImagePath
   send "choiceBehavior" && tHilitedImagePath to image tImgChoice
end rawKeyUp


on choiceBehavior tHilitedImagePath
   put "choice" & the last char of tImgChoice into tChoice
   put "live choice feedback" & comma & tChoice into tMessage
   chatMessage tMessage
   ## Tell server this student's choice.
end choiceBehavior



E N D   O F   C L I E N T   S T A C K   R E L A T E D

##########################################################
##########################################################

S T A R T   O F   S E R V E R   S T A C K   R E L A T E D


on mouseUp
 accept connections on port 1987 with message clientConnected
 ## Wait for all students/clients to connect.
end mouseUp



on clientConnected s
   ## A student/client has connected. When all expected clients
   ## are connected, initiate the game.
   wait 50 milliseconds with messages
   ## Bug? Without this line, read from socket takes a long time
   ## and returns empty.
   read from socket s for 1 line
   put line 1 of it into tChatMessage
   put tChatMessage & comma & s into gAllClientIPsArray[s]
   add 1 to field "numberOfClientsLoggedOn"
   if field "numberOfClientsLoggedOn" = field "expectedNumberOfClients" then
      put "yes" into field "allLogged"
      initiateGame
   end if
   read from socket s with message chatReceived
end clientConnected



on chatReceived s,data
   ## Student/client has sent a message.
   ## Perhaps it's a choice/answer ...
   put item 1 of data into tChatType
   switch tChatType
      case "live choice feedback"
         choice4AndTheBuzzState data
         break
   end switch
   read from socket s with message chatReceived
end chatReceived


on choice4AndTheBuzzState theChoice
   put item 2 of theChoice into tKey
   if gChoiceFeedbackTally[tKey] = 4 then
      ## Lock the buzzers, i.e., prevent clients
      ## from sending server their choices.
      put "buzz," before theChoice
   else
      put "no buzz," before theChoice
   end if
   put "live choice feedback" & LF into tChatMessage
   put tTimerPoints & comma & theChoice after tChatMessage
   broadcastToAllClients tChatMessage
end choice4AndTheBuzzState


on broadcastToAllClients message
   ## Tell all the students/clients who made what choice.
   put keys(gAllClientIPsArray) into tChatterList
   repeat for each line tArrayKey in tChatterList
      put gAllClientIPsArray[tArrayKey] into tArrayDataLine
      -- the client ID, the student ID, the client IP
      -- eg, Blitz-1,10000,127.0.0.1:1448
      put item 3 of tArrayDataLine into tSocket
      write message to socket tSocket
   end repeat
end broadcastToAllClients

E N D   O F   S E R V E R   S T A C K   R E L A T E D

##########################################################



More information about the use-livecode mailing list