一、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
二、创建WebSocket Handler
package cn.edu.tju.handler;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.Date;
@Component
public class MyMessageHandler extends TextWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
super.afterConnectionEstablished(session);
System.out.println("connection .........");
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
super.handleTextMessage(session, message);
System.out.println("server received:" + message.getPayload());
session.sendMessage(new TextMessage(new Date()+" Hello world"));
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("closed......");
}
}
三、配置WebSocket
package cn.edu.tju.config;
import cn.edu.tju.handler.MyMessageHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.TextWebSocketHandler;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private MyMessageHandler myMessageHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(webSocketHandler(),"/websocket")
.setAllowedOrigins("*");
}
@Bean
public TextWebSocketHandler webSocketHandler() {
return myMessageHandler;
}
}
四、简单的一个html测试页面
<!DOCTYPE HTML>
<html>
<head>
<title>WebSocket Demo</title>
</head>
<body>
<input id="text" type="text" /><br>
<button onclick="sendMessage()">发送消息</button><br>
<button onclick="closeWebSocket()">关闭连接</button>
<div id="message">
</div>
</body>
<script type="text/javascript">
var webSocket = null;
//判断WebSocket支持
if('WebSocket' in window){
webSocket = new WebSocket("ws://localhost:9093/websocket");
}
else{
alert('WebSocket is not supported');
}
//连接发生错误的回调方法
webSocket.onerror = function(){
alert('连接失败');
};
//连接成功建立的回调方法
webSocket.onopen = function(event){
alert('连接成功');
}
//接收到消息的回调方法
webSocket.onmessage = function(event){
setMessageInnerHTML(event.data);
}
//连接关闭的回调方法
webSocket.onclose = function(){
alert("连接已关闭");
}
//当窗口关闭时关闭websocket连接
window.onbeforeunload = function(){
webSocket.close();
}
//关闭连接
function closeWebSocket(){
webSocket.close();
}
//发送消息
function sendMessage(){
var message = document.getElementById('text').value;
webSocket.send(message);
}
//显示消息
function setMessageInnerHTML(innerHTML){
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
</script>
</html>
###########################################################################
服务端也可以如下创建:
package cn.edu.tju.config;
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();
}
}
package cn.edu.tju.component;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.common.collect.Sets;
@ServerEndpoint(value = "/webSocket")
@Component
public class WebSocketComponent {
//在线人数
private static AtomicInteger onlineClientCount = new AtomicInteger(0);
//guava 提供的线程安全的set类,可以用CopyOnWriteArraySet代替
private static Set<WebSocketComponent> webSocketSet = Sets.newConcurrentHashSet();
//与客户端的连接会话
private Session session;
//客户端连接成功时调用的方法
@OnOpen
public void onOpen(Session session) {
this.session = session;
//将新加入的客户端添加到Set
webSocketSet.add(this);
//增加在线人数
increaseOnlineClientCount();
System.out.println("client joined, current online client count is: " + getOnlineClientCount());
try {
sendMessageToAllClients("欢迎客户端" +this+"加入,当前在线人数为" + getOnlineClientCount());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
//收到客户端消息时调用的方法
@OnMessage
public void onMessage(String message, Session session) throws Exception{
System.out.println("Client message :" + message);
sendMessageToAllClients(message);
}
//有客户端失去连接时调用的方法
@OnClose
public void onClose() throws Exception{
webSocketSet.remove(this); //从set中删除
decreaseOnlineClientCount(); //在线数减1
System.out.println("Client left, current online client count is: " + getOnlineClientCount());
sendMessageToAllClients("客户端离开,当前客户端数量为: " + getOnlineClientCount());
}
//出现错误时调用的方法
@OnError
public void onError(Session session, Throwable error) {
System.out.println(error.getMessage());
}
//发送消息的方法
public void sendMessage(String message) throws Exception {
this.session.getBasicRemote().sendText(message);
}
//给所有的在线客户发送消息
public static void sendMessageToAllClients(String message) throws Exception {
for (WebSocketComponent item : webSocketSet) {
try {
item.sendMessage(message);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
//获取在线客户数量
public static synchronized AtomicInteger getOnlineClientCount() {
return onlineClientCount;
}
//增加在线客户数量
public static synchronized void increaseOnlineClientCount() {
WebSocketComponent.onlineClientCount.incrementAndGet();
}
//降低在线客户数量
public static synchronized void decreaseOnlineClientCount() {
WebSocketComponent.onlineClientCount.decrementAndGet();
}
}