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