前提
本篇文章適用于入門(mén)級(jí)別岸售,不做深入研究贤斜。
后臺(tái)springboot代碼
引入依賴(lài)
<!--websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
配置類(lèi)
@Configuration
public class CommonConfig {
/**
* websocket配置
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
websocket服務(wù)類(lèi)
@ServerEndpoint("/websocket/{username}")
@Slf4j
@Component
public class Websocket {
//靜態(tài)變量征讲,用來(lái)記錄當(dāng)前在線(xiàn)連接數(shù)。設(shè)計(jì)為安全的
private static int onlineCount = 0;
//concurrentHashMap分段鎖槐瑞,用來(lái)存放每個(gè)客戶(hù)端對(duì)應(yīng)的Websocket對(duì)象。
private static Map<String, Websocket> clients = new ConcurrentHashMap<String, Websocket>();
//與某個(gè)客戶(hù)端的連接會(huì)話(huà)鸳慈,需要通過(guò)它來(lái)給客戶(hù)端發(fā)送數(shù)據(jù)
private Session session;
private String username;
/**
* 連接建立成功調(diào)用的方法
* @param username
* @param session
*/
@OnOpen
public void onOpen(@PathParam("username") String username, Session session) {
this.username = username;
this.session = session;
Websocket.onlineCount++;
log.info("有一連接進(jìn)入拂募!當(dāng)前在線(xiàn)人數(shù)為" + onlineCount);
clients.put(username, this);
}
/**
* 連接關(guān)閉調(diào)用的方法
*/
@OnClose
public void onClose() {
clients.remove(username);
Websocket.onlineCount--;
log.info("有一連接關(guān)閉!當(dāng)前在線(xiàn)人數(shù)為" + onlineCount);
}
/**
* 收到客戶(hù)端消息后調(diào)用的方法
* @param message
*/
@OnMessage
public void onMessage(String message) {
System.out.println("收到客戶(hù)端的消息"+message);
sendMessage(message);
}
@OnError
public void onError(Session session, Throwable throwable) {
log.error("WebSocket發(fā)生錯(cuò)誤:" + throwable.getMessage());
}
public static void sendMessage(String message) {
// 向所有連接websocket的客戶(hù)端發(fā)送消息
// 可以修改為對(duì)某個(gè)客戶(hù)端發(fā)消息
for (Websocket item : clients.values()) {
item.session.getAsyncRemote().sendText(message);
}
}
}
測(cè)試請(qǐng)求方法
@RestController
@RequestMapping("/news")
public class NewsController {
@GetMapping("/send")
public String send(){
Websocket.sendMessage("這是websocket群發(fā)消息帅刊!");
return "發(fā)送消息成功";
}
}
前端VUE
這是在創(chuàng)建vue項(xiàng)目自帶的HelloWorld.vue文件里修改的
<template>
<div class="hello">
<h1>測(cè)試webSocket</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
created() { // 頁(yè)面創(chuàng)建生命周期函數(shù)
this.initWebSocket()
},
destroyed: function () { // 離開(kāi)頁(yè)面生命周期函數(shù)
this.websocketclose();
},
methods: {
initWebSocket: function () {
// WebSocket與普通的請(qǐng)求所用協(xié)議有所不同纸泡,ws等同于http,wss等同于https
this.websock = new WebSocket("ws://127.0.0.1:8031/websocket/test");
this.websock.onopen = this.websocketonopen;
this.websock.onerror = this.websocketonerror;
this.websock.onmessage = this.websocketonmessage;
this.websock.onclose = this.websocketclose;
},
websocketonopen: function () {
console.log("WebSocket連接成功");
},
websocketonerror: function () {
console.log("WebSocket連接發(fā)生錯(cuò)誤");
},
websocketonmessage: function (e) {
console.log(e.data); // console.log(e);
},
websocketclose: function (e) {
console.log("connection closed (" + e.code + ")");
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
測(cè)試
OK赖瞒!代碼部分已結(jié)束女揭,現(xiàn)在先啟動(dòng)后臺(tái)springboot,和前端vue栏饮。打開(kāi)頁(yè)面按下F12看日志打印吧兔。
image.png
非常好,這時(shí)候說(shuō)明前后端websocket已經(jīng)連接成功了袍嬉。
下面用你的工具(http測(cè)試工具境蔼,postman之類(lèi)的)測(cè)試推送消息接口。
image.png
很棒伺通,調(diào)用接口成功箍土,信息成功發(fā)送。下面看看前端是否收到罐监。
image.png
OK吴藻!大功告成!各位朋友弓柱!
good luck调缨!
后會(huì)有期!
有什么問(wèn)題也可以私信我或評(píng)論吆你,看到就會(huì)回復(fù)弦叶。