Java Servlet 初探 WebSocket
在 Java Servlet 中使用 WebSocket。
在 Servlet 中使用 WebSocket 的話比較不一樣,沒有要用到 Servlet API 了,取而代之的是 javax.websocket 這個包。
首先!我們要先下載 websocket 的相依性 ( 這次專案要裝的相依性也就僅此爾爾 )
<!-- https://mvnrepository.com/artifact/jakarta.websocket/jakarta.websocket-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.1.0</version>
<scope>provided</scope>
</dependency>
@ServerEndpoint("/websocket")
public class WebSocketServer {
@OnMessage
public void onMessage(String message, Session session) throws IOException, InterruptedException {
System.out.println("從您的網頁收到一封訊息: 「" + message + "」");
}
@OnOpen
public void onOpen() {
System.out.println("與客戶端建立連線了!");
}
@OnClose
public void onClose() {
System.out.println("連線關閉!");
}
@OnError
public void onError(Session session, Throwable t) {
System.out.println("連線發生錯誤!");
}
}
在我們的 WebSocket 中,是使用 @ServerEndpoint() 這個標註來註記他為 WebSocket 服務,裡面的參數當然就是指定訪問 url 的位置了!
在我們的物件中 分別又有四個事件:
- @OnOpen - 當與客戶端連線建立
- @OnClose - 當客戶端取消連線
- @OnError - 發生錯誤
- @OnMessage - 客戶端傳送訊息過來
其中分別是 @OnError 與 @OnMessage 會收到 Session 物件 (也就是會話物件) 透過這個 Session 物件,我們就可以與客戶端進行溝通。
可以是取得一些客戶端的基本查詢資訊,亦或是推送訊息給客戶端、關閉會話 等等... 那知道這些之後,來個簡單的範例吧!
public class WebSocketServer {
@OnMessage
public void onMessage(String message, Session session) throws IOException, InterruptedException {
session.getBasicRemote().sendText("從您的網頁收到一封訊息: 「" + message + "」");
int sendMessages = 0;
while (sendMessages < 10) {
Thread.sleep(500);;
sendMessages++;
session.getBasicRemote().sendText(
"伺服器推送第 " + sendMessages + " 筆訊息"
);
}
session.getBasicRemote().sendText("這是伺服器推送的最後一筆訊息 要再收到伺服起的訊息就再敲我一下吧!!");
// session.close(); // 關閉會話
}
@OnOpen
public void onOpen() {
System.out.println("與客戶端建立連線了!");
}
@OnClose
public void onClose() {
System.out.println("連線關閉!");
}
@OnError
public void onError(Session session, Throwable t) {
System.out.println("連線發生錯誤!");
}
}
阿如果前面的 Tomcat 環境忘了怎麽建議可以參考這篇!「Tomcat + Servlet + IntelliJ」
這裡還有簡單的 Vue 前端程式碼,也可以參考一下:
<template>
<div id="app">
<h2>伺服器回應訊息:</h2>
<div class="resp-box">
<p v-for="(respMsg, index) in respMsgArr" :key="index">
{{respMsg}}
</p>
</div>
<input type="text" v-model="msg">
<button @click="sendMsg">送出訊息</button>
</div>
</template>
<script>
export default {
name: 'App',
created () {
this.subWebSocket()
},
data () {
return {
mySocket: null,
msg: '', // 傳給伺服器的訊息
respMsgArr: [] // 伺服器回應過的訊息
}
},
methods: {
subWebSocket () {
console.log('連線中...')
this.mySocket = new WebSocket('ws://localhost:8080/web-socket/websocket')
// 註冊事件
this.mySocket.onopen = () => this.onOpen()
this.mySocket.onerror = () => this.onError()
this.mySocket.onmessage = (msg) => this.onMessage(msg)
},
/**
* 連線成功事件
*/
onOpen () {
console.log('連線成功')
},
/**
* 連線失敗事件
*/
onError () {
console.log('連結失敗')
},
/**
* 接受到伺服器訊息
*/
onMessage (msg) {
this.respMsgArr.push(msg.data)
},
sendMsg () {
this.mySocket.send(this.msg)
}
}
}
</script>
<style>
.resp-box {
padding: 10px;
border: 1px solid black;
}
</style>