使用websocket建立长连接,实现服务端向客户端发送消息
1.依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- @ServerEndpoint注解需要引入javaee规范 -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
2.开启对websocket的支持
@Configuration
public class WebSocketConfig
{
@Bean
public ServerEndpointExporter serverEndpointExporter()
{
return new ServerEndpointExporter();
}
}
3.服务端的建立
@ServerEndpoint("/websocket")
@Component // war包部署时,去掉该注解
public class WebSocketServer
{
static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
// 存储所有在线的socket连接
private static Map<String, WebSocketServer> webSocketMap = new LinkedHashMap<>();
// 当前在线数目
private static int count = 0;
// 会话连接,websocket连入时会创建一个WebSocketServer实例
private Session session;
// 连接建立
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketMap.put(session.getId(), this);
addCount();
log.info("新的连接加入:{}", session.getId());
}
// 接收消息
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到客户端{}消息:{}", session.getId(), message);
try
{
this.sendMessage("收到消息:" + message);
}
catch (Exception e)
{
e.printStackTrace();
}
}
// 错误处理
@OnError
public void onError(Throwable error, Session session) {
log.info("发生错误{},{}", session.getId(), error.getMessage());
}
// 关闭连接
@OnClose
public void onClose() {
webSocketMap.remove(this.session.getId());
reduceCount();
log.info("连接关闭:{}", this.session.getId());
}
// 发送消息
public void sendMessage(String message)
throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 发送自定义消息,当没有sid时则群发
*/
public static void sendInfo(String message, @PathParam("sid") String sid)
throws IOException {
log.info("推送消息到窗口" + sid + ",推送内容:" + message);
WebSocketServer.webSocketMap.forEach((k, v) -> {
try
{
// 这里可以设定只推送给这个sid的,为null则全部推送
if (sid == null) {
v.sendMessage(message);
} else if (k.equals(sid)) {
v.sendMessage(message);
}
}
catch (Exception e){
e.printStackTrace();
}
});
}
// 广播消息(群发)
public static void broadcast(String message) {
WebSocketServer.webSocketMap.forEach((k, v) -> {
try {
v.sendMessage(message);
}
catch (Exception e) {
e.printStackTrace();
}
});
}
// 获取在线连接数目
public static int getCount() {
return count;
}
// 操作count,使用synchronized确保线程安全
public static synchronized void addCount() {
WebSocketServer.count++;
}
public static synchronized void reduceCount() {
WebSocketServer.count--;
}
}
4.html5访问websocket
参考:https://www.runoob.com/html/html5-websocket.html