#创作灵感#:参考了
我的解决方案:
维护了一个sessionLocks
映射表,用于将会话的唯一标识符映射到对应的锁对象上。在sendMessageToSession
方法中,首先根据会话的唯一标识符获取对应的锁对象,然后对该锁对象进行加锁操作,执行完发送消息的操作后再释放锁对象。
这样就可以确保每个会话之间的操作互不干扰,解决了多客户端并发访问的问题。
希望这个示例能够帮助你理解如何处理多个会话的并发访问。
以下是一个简单的部分示例代码,演示了如何使用全局锁对象映射表来确保多个会话之间的操作互不干扰。
import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;@Component @Slf4j @ServerEndpoint("/websocket/{userId}") public class WebSocket {private Session session; private String userId; private static final String REDIS_TOPIC_NAME = "socketHandler";private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>(); private static Map<String, Session> sessionPool = new HashMap<String, Session>(); private Map<String, Lock> sessionLocks = new ConcurrentHashMap<>();public void pushMessage(String message) { log.info("【websocket消息】连接总数为:" + webSockets.size()); try { webSockets.forEach(ws -> { Session session = ws.session; if (session != null && session.isOpen()) { Lock sessionLock = getSessionLock(session.getId()); sessionLock.lock(); try { session.getAsyncRemote().sendText(message); } catch (Exception e) { log.error("发送消息时出现异常: " + e.getMessage()); }finally { sessionLock.unlock(); } } else { log.error("会话不存在或已关闭,无法发送消息"); } }); } catch (Exception e) { log.error("发送消息时出现异常: " + e.getMessage()); } } private Lock getSessionLock(String sessionId) { sessionLocks.putIfAbsent(sessionId, new ReentrantLock()); return sessionLocks.get(sessionId); }}