首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java WebSocket 實戰:原生 JSR-356 與 Spring WebSocket(含 STOMP)完整範例

     編輯:Java 相關知識

技術棧版本要求

  • Java 7+(JSR-356 標準 API)
  • Tomcat 7+ / Jetty 9.1+(容器實作)
  • Spring 4.0+(Spring WebSocket 支援)

一、原生 JSR-356 客戶端

@ClientEndpoint
public class SimpleClient {
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("Connected: " + session.getId());
    }
    @OnMessage
    public void onMessage(String msg) { System.out.println("收到: " + msg); }
    @OnError
    public void onError(Throwable t) { t.printStackTrace(); }
}

// 發起連線
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
Session session = container.connectToServer(SimpleClient.class, URI.create("ws://localhost:8081/log/log"));
session.getBasicRemote().sendText("Hello Server");

二、Spring 普通 WebSocket 端點

配置類

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(logHandler(), "/log");
    }
    @Bean
    public WebSocketHandler logHandler() {
        return new LogWebSocketHandler();
    }
}

處理器

public class LogWebSocketHandler extends TextWebSocketHandler {
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        System.out.println("Server 收到: " + payload);
        session.sendMessage(new TextMessage("Echo: " + payload));
    }
}

三、Spring STOMP over WebSocket(訊息代理模式)

啟用訊息代理配置

@Configuration
@EnableWebSocketMessageBroker
public class StompConfig extends AbstractWebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/hello").withSockJS(); // 支援 SockJS 降級
    }
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic"); // 簡易訊息代理
        registry.setApplicationDestinationPrefixes("/app");
    }
}

Controller 處理訂閱/廣播

@Controller
public class GreetingController {
    @MessageMapping("/hello")        // 客戶端發送到 /app/hello
    @SendTo("/topic/greetings")      // 廣播到訂閱 /topic/greetings 的客戶端
    public Greeting greet(HelloMessage msg) throws Exception {
        Thread.sleep(1000); // 模擬處理
        return new Greeting("Hello, " + msg.getName() + "!");
    }
}

四、瀏覽器端 SockJS + STOMP.js

var socket = new SockJS('/log/hello');
var stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
    stompClient.subscribe('/topic/greetings', function(greeting) {
        showGreeting(JSON.parse(greeting.body).content);
    });
});
function sendName() {
    stompClient.send("/app/hello", {}, JSON.stringify({ 'name': document.getElementById('name').value }));
}

五、關鍵協議細節

  • STOMP 幀格式:`COMMAND\nheader:value\n\nbody\0`
  • SockJS 提供 WebSocket 不可用時的 HTTP 長輪詢/Streaming 降級
  • Spring `SimpMessagingTemplate` 可在任意處廣播:`template.convertAndSend("/topic/notify", "訊息")`

選型建議

場景推薦方案
簡單雙向通訊、低延遲原生 JSR-356 / Spring TextWebSocketHandler
複雜訊息路由、廣播、訂閱、權限Spring STOMP + 簡易/外部 Broker (RabbitMQ/Kafka)
瀏覽器相容性要求高SockJS 降級
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved