I would say that a client expresses intent to the server to do the following
- Start attacking
- Stop attacking
- Execute a special attack
When a player enters combat on the server side, a simulation is started. The simulation examines the player's weapons and their swing timers and begins calculating when white-attacks (aka auto-attacks) occur to the target. When special attacks are requested, the simulation will carry those out if applicable.
As to how to delay on the server side, it can be as simply as once your first auto-attack happens and your weapon speed is 1.6 seconds, then the simulation will set the swing timer to 1.6 and for each update of the simulation, it will decrease the time that past since the last update. Once the swing timer reaches 0, an auto attack occurs if applicable and the variable is reset back to the weapon swing time and the process repeats.
From this point, the server performs the damage calculations and transmits that information to the client. All the client does is renders the information and nothing more. The server sends that entity XYZ took N damage. The client decrements the health of entity XYZ by N, perhaps adds some scrollable combat text to reflect N damage, adds an entry to the combat logs and proceeds.