- 使用@ServerEndpoint开发WebSocket
- 1.定义pom.xml
- 2.定义WebSocket处理类
- 3.配置ServerEndpointExporter Bean
- 3.使用Javascript来开发WebSocket客户端
- 4.主程序类
使用WebSocket能让客户端与服务端进行双向的实时通信。当客户端与服务端之间交互的内容较多或对实时性要求较高时,可使用WebSocket。 使用@ServerEndpoint开发WebSocket
Springboot的spring-boot-starter-websocket.jar为WebSocket提供了丰富的支持,使用这种方式来开发WebSocket服务器端程序非常简单,只要如下两步即可。
定义一个WebSocket处理类,该处理类有两种开发方式:
- 直接使用JDK提供的WebSocket注解修饰处理方法,并使用@ServerEndpoint注解修饰该处理类即可。
- 实现WebSocketHandler接口,并实现该接口中定义的各种处理方法。
采用第一种方式开发WebSocket处理类,这一步只需要在Spring容器中配置一个ServerEndpointExporter Bean即可。采用第二种方式开发WebSocket处理类,这一步就需要使用WebSocketConfigurer来配置WebSocket。
1.定义pom.xmlpom.xml
继承spring-boot-starter-parent,并添加spring-boot-starter-websocket.jar依赖
2.定义WebSocket处理类4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.2 org.crazyit ServerEndpoint 1.0-SNAPSHOT ServerEndpoint UTF-8 11 org.springframework.boot spring-boot-starter-websocket org.springframework.boot spring-boot-devtools true org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin
接下来定义WebSocket处理类,并在该类中定义连接成功、收到消息、出现错误、连接关闭时的处理方法。
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
@ServerEndpoint("/websocket/{name}")
public class WebSocketEndpoint
{
public static Map socketMap = new ConcurrentHashMap<>();
// 连接建立成功触发的方法
@OnOpen
public void onOpen(@PathParam("name") String name, Session session)
{
socketMap.put(session, name);
}
// 连接关闭时触发的方法
@OnClose
public void onClose(Session session)
{
socketMap.remove(session);
}
// 收到客户端消息后触发的方法
@OnMessage
public void onMessage(String message, Session session)
{
System.out.printf("收到来自%s的消息:%s%n", session, message);
try
{
var name = socketMap.get(session);
for (var client: socketMap.keySet()) // ①
{
client.getBasicRemote().sendText(name + "说:" + message);
}
} catch (IOException e)
{
e.printStackTrace();
}
}
// 发生错误时触发的方法
@OnError
public void onError(Session session, Throwable error)
{
System.out.println("发生错误");
socketMap.remove(session);
}
}
- 该处理类定义了onOpen()、onClose()、onMessage()、onError()四个方法,并分别使用了@OnOpen、@OnClose、@OnMessage、@OnError注解修饰,表明这四个方法分别在建立连接、关闭连接、收到消息、遇到错误时被触发。
- 使用这种方式开发WebSocket处理类更灵活,比如粗体字代码定义的onOpen()方法,该方法额外定义了一个用@PathParam修饰的形参,通过该形参即可获取路径参数。
- 上面处理类使用Map保存WebSocketSession与客户端之间的对应关系,每当服务器接收到客户端发送过来的消息时,程序都会通过循环遍历Map中的每一个WebSocketSession,并逐一向它们发送接收到的消息,这样任意客户端发送消息都会被广播给所有客户端。
如下配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig
{
@Bean
public ServerEndpointExporter serverEndpointExporter()
{
return new ServerEndpointExporter();
}
}
- 上面配置类在Spring容器中配置了一个ServerEndpointExporter Bean,它专门负责读取Bean类上的@ServerEndpoint注解,并将该Bean导出为WebSocket Endpoint
基于WebSocket的多人聊天
上面的Javascript代码用到了HTML5的WebSocket规范,该页面代码需要支持HTML5规范的浏览器中运行。
4.主程序类import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App
{
public static void main(String[] args)
{
SpringApplication.run(App.class, args);
}
}



