将 Java WebSockets (JSR-356) 与 SpringBoot 集成
Posted
技术标签:
【中文标题】将 Java WebSockets (JSR-356) 与 SpringBoot 集成【英文标题】:Integrating Java WebSockets (JSR-356) with SpringBoot 【发布时间】:2017-07-16 18:33:00 【问题描述】:在 SpringBoot 中部署 websocket 时遇到问题。我已经尝试了很多基于https://spring.io/blog/2013/05/23/spring-framework-4-0-m1-websocket-support、Using Java API for WebSocket (JSR-356) with Spring Boot 等的方法,但没有任何运气。
这是我正在尝试的:
网络套接字:
@ServerEndpoint(value="/socket/name", configurator = SpringConfigurator.class)
public class TestSocket
public ApiSocket()
@OnOpen
public void onOpen(
Session session,
@PathParam("name") String name) throws IOException
session.getBasicRemote().sendText("Hi " + name);
applications.properties:
server.contextPath=/api
主类:
@SpringBootApplication
public class Main
public static void main(String[] args) throws Exception
SpringApplication.run(Main.class, args);
根据上面的博客文章,这应该是所有需要的。我还尝试了描述的第二种方法,它涉及一个没有运气的 bean:
@Bean
public ServerEndpointExporter endpointExporter()
return new ServerEndpointExporter();
我正在尝试打开与 ws://localhost:8080/api/socket/John 的连接,并希望收到带有路径名的响应:
var socket = new WebSocket('ws://localhost:8080/api/socket/John');
握手期间的结果是 404。
【问题讨论】:
在您提供的代码中没有指定路径/api/
。基于此,我希望 404 能够准确响应您的请求。
/api 来自应用程序属性中的 server.contextPath 参数。
你找到答案了吗?同样的问题
是的,我有时间会尽快更新此评论。
你找"/socket/name"
上班了吗?
【参考方案1】:
您还必须在 Spring 配置中的 Bean 中添加 TestSocket,并从您的 TestSocket 中删除 configurator = SpringConfigurator.class
。
通常 Spring 通过它的 STOMP 协议覆盖普通的 java JSR 356 websocket,它是 websocket 的一部分。它也不像普通的 websocket 那样支持完全二进制消息。
您应该在配置中添加ServerEndpointExporter
:
@Configuration
public class EndpointConfig
@Bean
public ChatEndpointNew chatEndpointNew()
return new ChatEndpointNew();
@Bean
public ServerEndpointExporter endpointExporter()
return new ServerEndpointExporter();
让我们看看客户端 ge 连接的房间的完整聊天消息:
@ServerEndpoint(value="/chatMessage/room")
public class ChatEndpointNew
private final Logger log = Logger.getLogger(getClass().getName());
@OnOpen
public void open(final Session session, @PathParam("room")final String room)
log.info("session openend and bound to room: " + room);
session.getUserProperties().put("room", room);
System.out.println("session openend and bound to room: " + room);
@OnMessage
public void onMessage(final Session session, final String message)
String room = (String)session.getUserProperties().get("room");
try
for (Session s : session.getOpenSessions())
if(s.isOpen()
&& room.equals(s.getUserProperties().get("room")))
String username = (String) session.getUserProperties().get("username");
if(username == null)
s.getUserProperties().put("username", message);
s.getBasicRemote().sendText(buildJsonData("System", "You are now connected as:"+message));
else
s.getBasicRemote().sendText(buildJsonData(username, message));
catch(IOException e)
log.log(Level.WARNING, "on Text Transfer failed", e);
@OnClose
public void onClose(final Session session)
String room = (String)session.getUserProperties().get("room");
session.getUserProperties().remove("room",room);
log.info("session close and removed from room: " + room);
private String buildJsonData(String username, String message)
JsonObject jsonObject = Json.createObjectBuilder().add("message", "<tr><td class='user label label-info'style='font-size:20px;'>"+username+"</td>"+"<td class='message badge' style='font-size:15px;'> "+message+"</td></tr>").build();
StringWriter stringWriter = new StringWriter();
try(JsonWriter jsonWriter = Json.createWriter(stringWriter))
jsonWriter.write(jsonObject);
return stringWriter.toString();
请注意,您应该将 ChatEndpointNew 和 ServerEndpointExporter 添加到应用程序的主要 Spring 配置之外。 如果出现任何错误,请尝试以下操作:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
您也可以浏览this Spring 文档。
【讨论】:
我想知道为什么没有人赞成这个正确而仔细的答案!非常感谢。对我帮助很大 @susan097 您将带注释的端点添加到ServerEndpointExporter
的建议对您有所帮助。 servletEndpointExp.setAnnotatedEndpointClasses(AnnotatedEndPoint.class)
谢谢。
为了解决这个问题,我浪费了四个小时。 @susan097 非常感谢!您的建议有帮助!以上是关于将 Java WebSockets (JSR-356) 与 SpringBoot 集成的主要内容,如果未能解决你的问题,请参考以下文章
在 Tomcat 7 中运行 Java EE 7 WebSockets
Java 11:用Java处理HTTP和WebSockets的新方法!