1.引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
2.配置ServerEndpointExporter
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
這個(gè)bean會(huì)自動(dòng)注冊使用了@ServerEndpoint注解聲明的Websocket endpoint玩焰。
3.創(chuàng)建websocket的ServerEndpoint端點(diǎn)
@Component
@ServerEndpoint("/socket")
public class WebSocketServer {
/**
* 全部在線會(huì)話
*/
private static Map<String, Session> onlineSessions = new ConcurrentHashMap<>();
/**
* 當(dāng)客戶端打開連接:1.添加會(huì)話對象 2.更新在線人數(shù)
*/
@OnOpen
public void onOpen(Session session) {
onlineSessions.put(session.getId(), session);
}
/**
* 當(dāng)客戶端發(fā)送消息:1.獲取它的用戶名和消息 2.發(fā)送消息給所有人
* <p>
* PS: 這里約定傳遞的消息為JSON字符串 方便傳遞更多參數(shù)劲适!
*/
@OnMessage
public void onMessage(Session session, String jsonStr) {
}
/**
* 當(dāng)關(guān)閉連接:1.移除會(huì)話對象 2.更新在線人數(shù)
*/
@OnClose
public void onClose(Session session) {
onlineSessions.remove(session.getId());
}
/**
* 當(dāng)通信發(fā)生異常:打印錯(cuò)誤日志
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
* 公共方法:發(fā)送信息給所有人
*/
public void sendMessageToAll(String jsonMsg) {
onlineSessions.forEach((id, session) -> {
try {
session.getBasicRemote().sendText(jsonMsg);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
4.前端配置連接與接收消息
<script>
import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; // 默認(rèn)主題
Vue.use(ElementUI, {size: 'small'});
import '@/directives/directives.js'
import Locale from '@/mixins/locale';
import { t } from '@/locale';
/**
* WebSocket客戶端
*
* 使用說明:
* 1斩跌、WebSocket客戶端通過回調(diào)函數(shù)來接收服務(wù)端消息誉尖。例如:webSocket.onmessage
* 2、WebSocket客戶端通過send方法來發(fā)送消息給服務(wù)端腰鬼。例如:webSocket.send();
*/
function getWebSocket() {
/**
* WebSocket客戶端 PS:URL開頭表示W(wǎng)ebSocket協(xié)議 中間是域名端口 結(jié)尾是服務(wù)端映射地址
*/
var webSocket = new WebSocket('ws://10.10.10.3:9117/socket');//建立與服務(wù)端的連接
/**
* 當(dāng)服務(wù)端打開連接
*/
webSocket.onopen = function (event) {
console.log('WebSocket打開連接');
};
/**
* 當(dāng)服務(wù)端發(fā)來消息:1.廣播消息 2.更新在線人數(shù)
*/
webSocket.onmessage = function (event) {
console.log(event)
console.log('WebSocket收到消息:%c' + event.data, 'color:green');
//獲取服務(wù)端消息
var message = JSON.parse(event.data) || {};
console.log(message)//
};
/**
* 關(guān)閉連接
*/
webSocket.onclose = function (event) {
console.log('WebSocket關(guān)閉連接');
};
/**
* 通信失敗
*/
webSocket.onerror = function (event) {
console.log('WebSocket發(fā)生異常');
};
return webSocket;
}
var webSocket = getWebSocket();
/**
* 通過WebSocket對象發(fā)送消息給服務(wù)端
* 此處沒有主動(dòng)發(fā)消息給服務(wù)端赐稽,如果調(diào)用此方法,則會(huì)發(fā)送消息至socket服務(wù)端onMessage()方法上
*/
function sendMsgToServer() {
var $message = $('#msg');
if ($message.val()) {
webSocket.send(JSON.stringify({username: $('#username').text(), msg: $message.val()}));
$message.val(null);
}
}
export default {
}
5.實(shí)現(xiàn)后端推送消息至瀏覽器端
@Autowired
private WebSocketServer webSocketServer;//注入socket服務(wù)
@Override
public PuStatesResult queryPuStateUseInfo(QueryCondition condition) {
String sql = condition.generatorSql();
if(sql == null){
return null;
}
List<PuState> puStateList = null;
puStateList = puStateMapper.getPusBySql(sql);
if(puStateList == null || puStateList.size() == 0){
return null;
}
PuStatesResult result = new PuStatesResult();
result.setPuStateList(puStateList);
result.computePuStates();
if(false == condition.isWithDetail()){
result.setPuStateList(null);
}
//todo
Gson gson = new Gson();
String json = gson.toJson(result);
webSocketServer.sendMessageToAll(json);//調(diào)用第3節(jié)中的方法
return result;
}
此處是前端查詢時(shí)党瓮,服務(wù)器將一些數(shù)據(jù)發(fā)送至前端详炬,假如我們在實(shí)現(xiàn)有些前端數(shù)據(jù)顯示的時(shí)候,當(dāng)查詢一次后寞奸,如果沒有斷開連接呛谜,希望后端數(shù)據(jù)更新后,前端能接收最近數(shù)據(jù)蝇闭。那么可以在數(shù)據(jù)更新接口中呻率,調(diào)用自己實(shí)現(xiàn)的socket服務(wù)端邏輯,推送消息至服務(wù)端呻引,然后由服務(wù)端監(jiān)聽,并更新數(shù)據(jù)