Java websocket简单介绍和使用

公良征
2023-12-01

一、什么是websocket?(基于TCP的全双工通信协议

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

二、websocket session 发送文本消息两个方法方法的区别

  • session.getAsyncRemote()表示异步发送
  • session.getBasicRemote()表示同步发送

三、ConcurrentHashMap

concurrentHashMap是一个支持高并发更新与查询的哈希表(基于HashMap)。
在保证安全的前提下,进行检索不需要锁定。与hashtable不同,该类不依赖于synchronization去保证线程操作的安全。

四、实现websocket连接的代码

@Slf4j
@Component
@ServerEndpoint("/websocket/{sessionId}")
public class ProjectConsoleWs {
    public static ProjectConsoleWs service = new ProjectConsoleWs();
    /**
     * 存放所有在线的客户端 [sessionId, session]
     */
    private static final Map<String, Session> clients = new ConcurrentHashMap<>();
 
    public void sendMessage(String sessionId, String message) {
        if (!clients.containsKey(sessionId)) {
            log.error("未找到指定客户端{}的websocket连接!", sessionId);
            return;
        }
 
        this.onMessage(message, clients.get(sessionId));
        log.info("准备向客户端程序{}发送消息:{}", sessionId, message);
    }
 
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            log.error("消息发送失败!", e);
        }
    }
 
    @OnOpen
    public void onOpen(@PathParam("sessionId") String sessionId, Session session) {
        if (clients.containsKey(sessionId)) {
            log.warn("客户端程序{}已有连接,无需建立连接", sessionId);
            return;
        }
        session.setMaxIdleTimeout(0);
        clients.put(sessionId, session);
        log.info("客户端程序{}建立连接成功!------>当前在线人数为:{}", sessionId,getOnlineCount());
    }
 
    @OnClose
    public void onClose(@PathParam("sessionId") String sessionId, Session session) {
        if (!clients.containsKey(sessionId)) {
            log.warn("客户端程序{}没有连接,无需断开连接", sessionId);
            return;
        }
 
        clients.remove(sessionId);
        log.info("客户端程序{}断开连接成功!------>当前在线人数为:{}", sessionId,getOnlineCount());
    }
 
    @OnError
    public void onError(Session session, Throwable throwable) {
        log.info("连接{}发生错误!", session.getId());
        throwable.printStackTrace();
    }
 
    public boolean sessionIsOpen(String sessionId){
        return clients.get(sessionId).isOpen();
    }
 
    public synchronized int getOnlineCount(){
        return clients.size();
    }
 
}
@Configuration
public class WebSocketConfig {
 
    @Bean("serverEndpointExporter")
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
 
}
 类似资料: