play建议可能缺少什么。 在春季,春季/码头/雅加达/EE10内容的春季/雅加达/EE10内容很少有相互冲突。 我需要使用Customizer设置处理程序?
main:
@EnableWebMvc
@SpringBootApplication
public class MyBootApplication...
MyWebSocketConfig class:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.context.annotation.Bean;
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;
import org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
@Configuration
@EnableWebSocket
public class MyWebSocketConfig implements WebSocketConfigurer {
@Autowired
private MyWebSocketHandler myWebSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry
.addHandler(myWebSocketHandler, "/init")
.setHandshakeHandler(handshakeHandler())
.setAllowedOrigins("*");
}
@Bean
public DefaultHandshakeHandler handshakeHandler() {
JettyRequestUpgradeStrategy strategy = new JettyRequestUpgradeStrategy();
strategy.addWebSocketConfigurer(configurable -> {
configurable.setInputBufferSize(8192);
configurable.setIdleTimeout(Duration.ofSeconds(600));
});
return new DefaultHandshakeHandler(strategy);
}
}
gradle deps
implementation 'org.springframework:spring-web:6.2.1'
implementation 'org.springframework:spring-orm:6.2.1'
implementation 'org.springframework:spring-aop:6.2.1'
implementation 'org.springframework:spring-tx:6.2.1'
implementation 'org.springframework:spring-beans:6.2.1'
implementation 'org.springframework:spring-core:6.2.1'
implementation 'org.springframework:spring-jcl:6.2.1'
implementation 'org.springframework:spring-expression:6.2.1'
implementation 'org.springframework:spring-jdbc:6.2.1'
implementation 'org.springframework:spring-webmvc:6.2.1'
implementation 'org.springframework:spring-context:6.2.1'
implementation 'org.springframework:spring-websocket:6.2.1'
implementation 'org.springframework.data:spring-data-jpa:3.3.3'
implementation 'org.springframework.data:spring-data-commons:3.3.3'
implementation 'org.springframework.security:spring-security-core:6.3.6'
implementation 'org.springframework.security:spring-security-web:6.3.6'
implementation 'org.springframework.security:spring-security-config:6.3.6'
implementation 'org.springframework.boot:spring-boot-starter-web:3.3.7'
implementation("org.springframework.boot:spring-boot-starter-jetty:3.3.7") {
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
}
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.3.7'
implementation 'org.springframework.boot:spring-boot-starter-cache:3.3.7'
implementation 'org.springframework.boot:spring-boot-starter-log4j2:3.3.7'
implementation 'org.springframework.boot:spring-boot-starter-websocket:3.3.7'
implementation 'org.springframework.boot:spring-boot-autoconfigure:3.3.7'
implementation 'org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.7'
尝试了许多不同的依赖项,结果从“找到的jsr-356兼容提供商...”到此无效提供商。
spring引导-Websocker服务器示例
spring启动3.x
JDK17
Websocket(Jakarta Websocket)
ws-server
├── build.gradle
├── _build.gradle.kts
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ └── wsserver
│ ├── DemoApplication.java
│ ├── HelloWebSocketServerEndpoint.java
│ └── WebSocketConfig.java
└── resources
└── application.properties
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-wsserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-wsserver</name>
<description>WebSocket Server for Spring Boot</description>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
<build>
<finalName>ws-server</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
plugins {
id 'org.springframework.boot' version '3.3.3'
id 'io.spring.dependency-management' version '1.1.0'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
description = 'WebSocket Server for Spring Boot'
sourceCompatibility = '17'
targetCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-websocket'
}
bootJar {
archiveFileName = 'ws-server.jar'
}
Build.gradle.kts
plugins {
id("org.springframework.boot") version "3.3.3"
id("io.spring.dependency-management") version "1.1.0"
java
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
description = "WebSocket Server for Spring Boot"
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-websocket")
}
tasks.named<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJar") {
archiveFileName.set("ws-server.jar")
}
package com.example.wsserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
package com.example.wsserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
@EnableWebSocket
public class WebSocketConfig {
private static final Logger LOG = LoggerFactory.getLogger(WebSocketConfig.class);
@Bean
public ServerEndpointExporter serverEndpointExporter() {
LOG.info(">>>> serverEndpointExporter()");
return new ServerEndpointExporter();
}
}
HelloweBockocketServerendPoint.javapackage com.example.wsserver;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
@Component
@ServerEndpoint("/websocket")
public class HelloWebSocketServerEndpoint {
private static final Logger LOG = LoggerFactory.getLogger(HelloWebSocketServerEndpoint.class);
//Save all connected Sessions
private static final CopyOnWriteArraySet<Session> sessions = new CopyOnWriteArraySet<>();
public HelloWebSocketServerEndpoint() {
LOG.info(">>>> init");
}
@OnOpen
public void onOpen(Session session) {
sessions.add(session);
LOG.info("WebSocket opened: " + session.getId());
broadcastMessage("Client " + session.getId() + " joined!");
}
@OnMessage
public void onMessage(String message, Session session) {
LOG.info("Message received from " + session.getId() + ": " + message);
try {
session.getBasicRemote().sendText("Echo: " + message);
} catch (IOException e) {
LOG.warn("IOException: {}", e);
}
}
@OnClose
public void onClose(Session session, CloseReason reason) {
sessions.remove(session);
LOG.info("WebSocket closed: " + session.getId());
broadcastMessage("Client " + session.getId() + " left.");
}
@OnError
public void onError(Session session, Throwable throwable) {
LOG.error("WebSocket error: " + session.getId());
throwable.printStackTrace();
}
//Broadcast message to all connected Clients
private void broadcastMessage(String message) {
LOG.info("broadcast >>>>> {}", message);
for (Session session : sessions) {
try {
session.getBasicRemote().sendText("broadcast >>>>> " + message);
} catch (IOException e) {
LOG.warn("IOException: {}", e);
}
}
}
}
application.propertiesspring.application.name=demo
-maven-构建和运行mvn clean package
runjava -jar target/ws-server.jar
级 - 构建和运行build
gradle clean build
runjava -jar build/libs/ws-server.jar
项目树
ws-client-JDK
├── build.gradle
├── _build.gradle.kts
├── pom.xml
└── src
└── main
└── java
└── com
└── example
└── wsclient
└── Main.java
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jdk-wsclient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jdk-wsclient</name>
<description>WebSocket Client for JDK</description>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<build>
<finalName>ws-client</finalName>
</build>
</project>
Build.gradle
在build.gradle和build.gradle.kts.之间选择一个
plugins {
id 'java'
id 'application'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
application {
mainClass.set('com.example.wsclient.Main')
}
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
jar {
archiveBaseName.set('ws-client')
}
plugins {
java
application
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
application {
mainClass.set('com.example.wsclient.Main')
}
tasks.withType<JavaCompile>().configureEach {
options.encoding = "UTF-8"
}
tasks.jar {
archiveBaseName.set("ws-client")
}
package com.example.wsclient;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.util.concurrent.CompletionStage;
public class Main {
public static void main(String[] args) throws Exception {
// Building HttpClient
HttpClient client = HttpClient.newHttpClient();
// Establishing a WebSocket Connection
WebSocket webSocket = client.newWebSocketBuilder()
.buildAsync(URI.create("ws://localhost:8080/websocket"), new WebSocketListener())
.join();
// Send Message
webSocket.sendText("Hello WebSocket! From JDK WebSocket Client", true);
// Wait for a while to make sure you receive a response
Thread.sleep(3000);
// Close Connection
webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "Bye").join();
}
// Custom WebSocket Listener
private static class WebSocketListener implements WebSocket.Listener {
@Override
public void onOpen(WebSocket webSocket) {
System.out.println("Connected to WebSocket!");
webSocket.request(1); // Request next message
}
@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
System.out.println("Received: " + data);
webSocket.request(1); // Continue to request the next message
return null;
}
@Override
public void onError(WebSocket webSocket, Throwable error) {
System.err.println("Error: " + error.getMessage());
}
@Override
public CompletionStage<?> onClose(WebSocket webSocket, int statusCode, String reason) {
System.out.println("Closed with status " + statusCode + ": " + reason);
return null;
}
}
}
linux命令:
build
mvn clean package
run
java -cp "target/ws-client.jar" com.example.wsclient.Main
级 - 构建和运行
build
gradle clean build
run
cd build/distributions
unzip ws-client-JDK-0.0.1-SNAPSHOT.zip
# build/distributions/ws-client-JDK-0.0.1-SNAPSHOT/bin
cd ws-client-JDK-0.0.1-SNAPSHOT/bin
./ws-client-JDK
java -cp "build/libs/ws-client-0.0.1-SNAPSHOT.jar" com.example.wsclient.Main
java应用程序使用嵌入式码头11与Jakarta Websocket:
Cannot连接到Jetty WebsocketV11