WebScoket使用实例

69 阅读1分钟

WebScoket后端的使用

  1. Spring Boot中的使用
  • 在pom.xml中引入相关依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    <version>${websocket.version}</version>
</dependency>
  • 新增一个【GreetingWebSocketHandler】类
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Configuration
public class GreetingWebSocketHandler extends TextWebSocketHandler {

    public static final ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
    public static final ExecutorService executorService = Executors.newSingleThreadExecutor();


    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.debug("连接成功:{}", session.getId());
        super.afterConnectionEstablished(session);
        // 将新连接的会话存储起来
        sessions.put(session.getId(), session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 处理从客户端发送过来的消息
        sendMessage(session.getId() + ",接收数据成功:" + message.getPayload());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
        // 移除关闭的会话
        sessions.remove(session.getId());
        log.debug("关闭连接成功,关闭连接:{};剩余连接:{}", session.getId(), sessions);
    }

    /**
    * 用于发送消息给前端
    */
    public static void sendMessage(String message) {
        // 使用线程的方式进行发送,防止并发导致报错
        executorService.submit(() -> {
            try {
                for (WebSocketSession session : sessions.values()) {
                    if (session.isOpen()) {
                        session.sendMessage(new TextMessage(message));
                    } else {
                        log.debug("websocket已关闭: " + session.getId());
                    }
                }
            } catch (Exception e) {
                log.error("发送消息失败", e);
            }
        });
    }
}
  • 增加config配置
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    private final GreetingWebSocketHandler greetingWebSocketHandler;

    public WebSocketConfig(GreetingWebSocketHandler greetingWebSocketHandler) {
        this.greetingWebSocketHandler = greetingWebSocketHandler;
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(greetingWebSocketHandler, "/ws").setAllowedOrigins("*");
    }
}
  • 发送数据给前端
public class websocketTest {
    private static void main(String[] args){
        Map<String, Object> map = new HashMap<>();
        map.put("title", "发送给前端的数据");
        GreetingWebSocketHandler.sendMessage(JSON.toJSONString(map));
    }
}
  1. 前端
const socket = new WebSocket(`ws://localhost:8080/ws`)
socket.onerror = (event: any) => {
    console.error("WebSocket连接错误:", event)
}
socket.open = (event: any) => {
    console.log("WebSocket is open now.");
}
socket.onmessage = (event: any) => {
    console.log("接收后端返回的数据:", event.data)
}
  1. 其他相关