We know when users login, we send and receive chatroom messages.. but how do we know when users disconnect?
Let's write some code to handle disconnects and display a message
*** [username] disconnected
when a socket disconnects.
How will we accomplish this? With more channels, of course!
- Whenever a ChatUser fails to read/write to its connection socket, we will send a message on the
ChatRoom.disconnect
channel to notify theListenForMessages
loop that the socket has been disconnected. - When such a message is received by the
ChatRoom
, remove it from theusers
map and broadcast a message to the rest of the clients saying it's disconnected.
- Find the
ChatRoom.Logout
function. Add some code that does the following: - 🌟 Send the supplied
username
to thecr.disconnects
channel.
Stuck on any of the steps above? Ask your TA, or see the solution!
- Update the
ListenForMessages
loop to handle messages oncr.disconnects
: - 🌟 Add a
case
statement that reads theusername
fromcr.disconnects
- 🌟 if the
username
is in thecr.users
map: 1. 🌟 callClose()
on theChatUser
object and remove it from the map. 1. 🌟 callBroadcast
to send a message:*** [username] has disconnected
Stuck on any of the steps above? Ask your TA, or see the solution!
-
Now that we have
Logout
implemented, let's callLogout
whenever the ChatUser read and write loops have errors reading or writing from the socket. -
Update
ChatUser.ReadIncomingMessages
so that it does the following:
1. :star2: If cu.ReadLine() returns an error, do not write a message to the `chatroom.incoming` queue.
Instead, call `chatroom.Logout` with the current username.
1. :star2: Add some logic that checks if `cu.disconnect` is set, then exit the loop.
[Stuck on any of the steps above? Ask your TA, or see the solution!](code/07-logouts/chat.go#L115-L121)
- Update
ChatUser.WriteOutgoingMessages
so that:
1. :star2: If cu.ReadLine() returns an error, do not write a message to the queue. Instead,
call `chatroom.Logout` with the current username.
1. :star2: Add some logic that checks if `cu.disconnect` is set, then exit the loop.
[Stuck on any of the steps above? Ask your TA, or see the solution!](code/07-logouts/chat.go#L133-L141)
- Finally, let's implement
ChatUser.Close
. This will set thedisconnect
variable and close the socket.
func (cu *ChatUser) Close() {
// TODO: close the socket
}
- 🌟 In
Close()
, setChatUser.disconnect = true
- 🌟 Close the
ChatUser.conn
Stuck on any of the steps above? Ask your TA, or see the solution!
- Now when a user disconnects, you'll see a disconnect message!
$ nc localhost 6677
Welcome to Jen's chat server!
Please enter your username: funcuddles
Welcome, funcuddles
*** funcuddles just joined the chatroom
*** bob just joined the chatroom
hello this is dog
[funcuddles] hello this is dog
[bob] bye funcuddles, I gotta go!
*** bob has disconnected