Hmm powinieneś jedną warstwę wyżej trzymać połączenia, bo clienta po id jaki przysyła jsonem sprawdzasz, a można sprawdzać po prostu po tcp połączeniu.
Jak używasz wss, czyli szyfrowany websocket to możesz przy pierwszym połączeniu odebrać token i jeśli jest poprawny to zaakceptować połączenie, a jak nie to zerwać czyli zrobić takie uwierzytelnianie, żeby potwierdzić, że jest się tym samym zalogowanym użytkownikiem co na stronie, czyli po zalogowaniu na stronie do websocketa dodaje się ten token.
A każde połączenie i tak jest unikalne, to tworzysz sobie ConnectionManagera, tam trzymasz hash mapę/vector połączeń i każde zerwane potem usuwasz z tej listy.
Jak wyjątek pójdzie czy w jakiś inny sposób dowiesz się o zerwaniu połączenia to wykasowujesz z listy.
Jak chcesz do kogoś konkretnego odpisać to możesz przeszukać listę, jak odpowiadasz od razu to nic nie musisz robić bo masz jego połączenie przy odbiorze.
A jak chcesz zrobić broadcast do wszystkich to iterujesz po tej liście.
A potwierdzenie to możesz odesłać websocketem jakiś message, {"status":"200"}
tylko takie coś jest problematyczne, bo wiadomości są async czyli jak przyjdzie to nie wiesz od czego przyszedł ten status, byś musiał jeszcze id taska dać, który jest wykonywany i to tak będzie źle wyglądało, zależy od aplikacji, bo jeśli tylko updatujesz widok to nie ma sensu odpisywać, że się odebrało, bo to i tak jest w sumie na tcp warstwie wykrywane jak wiadomość nie doszła.
W sumie zależy do czego to potrzebne.
Chyba, że klient coś zleca do zmiany, wtedy wysyłasz {"ops":"update", "price":"357}
nic nie robisz więcej, serwer dostaje procesuje i odsyła ci np. {"ops":"update_widok": "id":"34", "price":"357"}
wtedy masz pewność, że wszystko się poprawnie wykonało, bo serwer zwrócił zaaktualnioną wersję jakby się nie udało to by nie odesłał i widok też by się nie zmienił.
A jak ktoś dopiero będzie korzystał z usługi to mu z serwera zassie najświeższe informacje.