websocket Java 客户端和服务端例子(二)
2021-05-22 本文已影响0人
樱花舞
此篇文章使用的是spring 包下的类来实现简单的Java websocket 服务端和客户端。
1 引入包依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2 创建服务端
2.1 注册端点
创建服务端很简单,使用@EnableWebSocket注解声明使用websocket,实现WebSocketConfigurer,在WebSocketHandlerRegistry的addHandler方法中添加消息处理的handler以及端点,其作用和@ServerEndpoint类似。
@Configuration
@EnableWebSocket
public class ServerConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(new ServerHandler(),"/sp");
webSocketHandlerRegistry.addHandler(new ServerHandler2(),"/sp2");
}
}
2.2 消息处理handler
继承AbstractWebSocketHandler,可以处理收到文本、二进制、ping消息;如果只有文本消息,可以继承TextWebSocketHandler;如果只有二进制消息,可以继承BinaryWebSocketHandler。
handler的处理方法可以与tomcat包的注解做个对比:
spring | tomcat |
---|---|
afterConnectionEstablished | @OnOpen |
afterConnectionClosed | @OnClose |
handleTransportError | @OnError |
handleMessage | @OnMessage |
public class ServerHandler extends AbstractWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println(session.getId() + "客户连接");
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
System.out.println("收到文本消息" + session.getId() + ":" + message.getPayload());
//发送数据给客户端
session.sendMessage(new TextMessage("服务端收到:" + message.getPayload()));
}
@Override
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
System.out.println("二进制消息");
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println(session.getId() + "关闭连接");
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println(session.getId() + "发生错误");
exception.printStackTrace();
}
}
2.3 拦截器
可以在客户端与服务端连接成功前后做拦截,拦截器继承HttpSessionHandshakeInterceptor,并添加到WebSocketHandlerRegistry,拦截器添加在哪个端点,就会只拦截哪个端点的。
拦截器实现:
public class ServerInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
//获取端点携带的参数
String name = ((ServletServerHttpRequest) request).getServletRequest().getParameter("name");
System.out.println("before name="+name);
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
String name = ((ServletServerHttpRequest) request).getServletRequest().getParameter("name");
System.out.println("after name="+name);
super.afterHandshake(request, response, wsHandler, ex);
}
}
端点注册添加拦截器,ServerInterceptor只对/sp起作用,ServerInterceptor2对/sp2起作用。
@Configuration
@EnableWebSocket
public class ServerConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(new ServerHandler(),"/sp").addInterceptors(new ServerInterceptor());
webSocketHandlerRegistry.addHandler(new ServerHandler2(),"/sp2").addInterceptors(new ServerInterceptor2());
}
}
3 创建客户端
3.1 实现客户端handler
客户端也是继承AbstractWebSocketHandler实现消息处理。
public class ClientHandler extends AbstractWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println(session.getId()+"客户连接");
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
System.out.println("收到文本消息" + session.getId() + ":" + message.getPayload());
}
@Override
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
System.out.println("二进制消息");
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println(session.getId() + "关闭连接");
}
}
public class Client {
public static void main(String[] args) {
StandardWebSocketClient client = new StandardWebSocketClient();
ClientHandler handler = new ClientHandler();
//连接带参数
String url = "ws://localhost:8080/sp2?name=quit";
ListenableFuture<WebSocketSession> future = client.doHandshake(handler,url);
try (WebSocketSession session = future.get()){
session.sendMessage(new TextMessage("发送数据111"));
session.sendMessage(new TextMessage("发送数据2222"));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}