WebSocket的概念原理网上很多,就不赘述了,本文主要是讲解了如何在SpringBoot项目中使用WebSocket。
首先,要在pom中引入相关jar包,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
之后,增加配置类。特别注意,不能遗漏该配置类,否则在前端链接时会报404。
package com.freddy.websocket.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* webSocket配置类
* @author freddy
* @version V1.0, 2019-8-6
*/
@Configuration
public class WebSocketConfig {
/**
* ServerEndpointExporter对象用于管理WebSocket服务类的注册
* @return ServerEndpointExporter对象
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
为了后续的使用方便,我写了一个基础类,在实际开发中,如果只提供单个WebSocket服务的话,其实可以不用这个基础类。
package com.freddy.websocket.socket;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
/**
* WebSocket基础类,提供部分基础方法
* @author freddy
* @version V1.0, 2019-8-6
*/
public class BaseWebSocket {
/** 线程安全的set集合,用于存放该链接所有的webSocket连接对象 */
private static CopyOnWriteArraySet<BaseWebSocket> webSocketSet = new CopyOnWriteArraySet<BaseWebSocket>();
/** 当前连接对象的session对象 */
private Session session;
/**
* 有型的连接对象和服务器建立连接时调用的方法
* @param session 当前链接的session对象
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
addSocket(this);//加入set中
System.out.println("有新的客户端[" + session.getId() + "]接入,当前客户端数量:" + countSocket());
}
/**
* 连接关闭时调用的方法
*/
@OnClose
public void onClose() {
System.out.println("有链接断开,当前连接数量:" + countSocket());
removeSocket(this); //从set中删除
}
/**
* 服务端接收到消息时调用的方法
* @param message 消息内容
* @param session 连接对象的session
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("来自客户端[" + session.getId() + "]的消息:" + message);
}
/**
* 发生异常时调用的方法
* @param session 发生异常的连接对象的session
* @param error 异常对象
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println(error.getMessage());
}
/**
* 给当前对象发送消息
* @param message 消息内容
* @throws IOException
*/
protected void sendMessage(String message) throws IOException {
sendMessage(this.session, message);
}
/**
* 给指定对象发送消息
* @param session 要发送消息的连接对象的session
* @param message 消息内容
* @throws IOException
*/
public void sendMessage(Session session,String message) throws IOException {
session.getBasicRemote().sendText(message);
System.out.println("发送消息给客户端[" + session.getId() + "]:" + message);
}
/**
* 群发消息,给所有链接对象发送消息
* @param message 消息内容
* @throws IOException
*/
public static void sendGroup(String message) throws IOException {
for (BaseWebSocket item : getWebSocketSet()) {
try {
item.sendMessage(message);
} catch (IOException e) {
continue;
}
}
}
/**
* 添加webSocket连接对象
* @param webSocket 连接对象
* @return 是否成功
*/
@SuppressWarnings("static-access")
public boolean addSocket(BaseWebSocket webSocket){
return this.webSocketSet.add(webSocket);
}
/**
* 删除webSocket连接对象
* @param webSocket 连接对象
* @return 是否成功
*/
@SuppressWarnings("static-access")
public boolean removeSocket(BaseWebSocket webSocket){
return this.webSocketSet.remove(webSocket);
}
/**
* 计算当前连接对象
* @return 当前连接对象数
*/
@SuppressWarnings("static-access")
public int countSocket(){
return this.webSocketSet.size();
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public static CopyOnWriteArraySet<BaseWebSocket> getWebSocketSet() {
return webSocketSet;
}
}
服务类因为只是测试用,所以没重写任何方法,只是配置了一个地址:
package com.freddy.websocket.socket;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
/**
* webSocket服务类
* @author freddy
* @V1.0, 2019-8-6
*/
@Component
@ServerEndpoint(value = "/websocket")
public class WebSocketTest extends BaseWebSocket{
}
到这里,后台代码部分就OK了,只要启动项目,后台的服务就启动了。要特别说明一点,服务类必须要托管到spring容器中,在代码中的体现就是“@Component”,否则无法被服务注册管理类获取到。
前端代码如下,将下面代码的地址改一改,直接在控制台执行即可。
var ws = new WebSocket("ws:localhost:9013/webSocketDemo/websocket");
//连接成功时调用
ws.onopen = function(evt){
console.log("成功连接到服务器");
};
//接收到服务器的消息时调用
ws.onmessage = function(evt){
console.log("接收到来自服务器的消息:" + evt.data);
};
//连接关闭时调用
ws.onclose = function(evt){
console.log("连接已关闭");
};
尾声:本文只记录了WebSocket的基本应用,是为了让初学者能快速的搭建起后台的WebSocket服务,后台发送消息也只支持文本格式,但是在实际应用中,可以有更多的扩展,这个大家就自己研究了。