anchor.diff:                  match cmd with
                   | "new message" ->
                       let textMessage = packet.Data.[1].ToObject<string>()
  -                    logVerbose (sprintf "Received %s" textMessage)
  -                    socket.Broadcast (chatPacket "new message" { username = defaultArg state.userName ""; message = textMessage })
  +                    let userName = defaultArg state.userName "???"
  +                    logVerbose (sprintf "[%s] %s" userName textMessage)
  +                    socket.Broadcast (chatPacket "new message" { username = userName; message = textMessage })
                       state
                   | "add user" ->
                       match state.userName with
  
positive.code:         let! p = socket.Receive()
          match p with
          | Some packet ->
              log.info (eventX (sprintf "< %A" packet))
              match packet.EventId with
              | Some id -> socket.Send({ Packet.ofType Ack with EventId = Some id })
              | None -> ()
  
negative.code:                     logVerbose (sprintf "Unknown command: %s" cmd)
                      state
  
              return! handlePacket newState socket
          | None ->
              let userName = defaultArg state.userName "???"
              logVerbose (sprintf "[%A] LEAVE" userName)
              match state.userName with
              | Some userName ->
                  Interlocked.Decrement(&userCount) |> ignore
                  socket.Broadcast (chatPacket "user left" { UserJoinedEvent.username = userName; numUsers = userCount })
              | None -> ()
              return ()
      }
  
      let app =
          choose [
              socketio (handlePacket State.empty)
              GET >=> choose [
                  browseHome
              
  