WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务器主动向客户端推送数据。
WebSocket的主要特点:
- 全双工通信:客户端和服务器之间的数据可以同时双向传输
- 低延迟:由于是持久连接,所以不需要每次通信都重新建立连接,这大大减少了延迟。
- 节省带宽:WebSocket只需要一次握手,后续的数据传输都是基于这个连接,因此相对HTTP轮询来说更加节省带宽。
WebSocket的基本使用流程:
- 客户端发起请求:客户端发起一个WebSocket请求到服务器
- 握手阶段:服务器同意请求后,双方进入全双工模式。
- 数据传输:客户端和服务器客厅通过send()方法发送数据,通过onmessage事件处理接收到的数据。
- 关闭连接:当不再需要通信时,可以调用close()方法关闭连接。
服务器(SpringBoot)示例代码
依赖引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocket配置类
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpoint() {
return new ServerEndpointExporter();
}
}
业务处理类
@Slf4j
@Component
@ServerEndpoint("/websocket/{username}")
public class WebSocketTest {
private Session session;
private String username;
private static ConcurrentHashMap<String, WebSocketTest> webSocketSet = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
// 新的连接建立时执行,并且记录用户名
this.session = session;
this.username = username;
webSocketSet.put(username, this);
}
@OnMessage
public void onMessage(String message, Session session) {
// 接收到前端消息时执行
System.out.println("Received: " + message);
try {
session.getBasicRemote().sendText("Response from server: " + message);
} catch (IOException e) {
{
e.printStackTrace();
}
}
}
@OnClose
public void onClose (Session session, CloseReason closeReason){
webSocketSet.remove(this.username);
}
@OnError
public void onError (Session session, Throwable throwable){
// 发生错误时执行
System.out.println("Error ... " + session.getId());
throwable.printStackTrace();
}
public void sendMessage2User(String message,String username) {
try {
webSocketSet.get(username).session.getBasicRemote().sendText(message);
} catch (IOException e) {
log.error("method=sendMessage2User||msg=send msg to user error", e);
}
}
public void sendMessage() {
String filePath = "C:/Users/heal/Desktop/1.txt"; // 替换为你的文件路径
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
// username需要从客户端传入,我这里只是测试,所以写死
sendMessage2User(line,"admin");
}
} catch (IOException e) {
e.printStackTrace();
}
}
服务器记录每次连接的用户名,用于每次发送请求的session认证
客户端(vue)调用代码示例
import Vue from 'vue'
const WebSocketPlugin = {
install(Vue, options) {
const ws = new WebSocket('wss://127.0.0.1:8443/webserver/websocket')
Vue.prototype.$websocket = {
send(message) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(message)
}
},
onMessage(callback) {
ws.onmessage = callback
},
onOpen(callback) {
ws.onopen = callback
},
onClose(callback) {
ws.onclose = callback
},
onError(callback) {
ws.onerror = callback
}
}
Vue.mixin({
created() {
if (this.$options.websocket) {
this.$websocket.onMessage((message) => {
// 处理接收到的消息
console.log(message)
})
}
}
})
}
}
export default WebSocketPlugin
send() {
this.$websocket.send('Hello, WebSocket!')
},
也可以使用apifox直接发请求到服务器
这样就吧文件中的内容实时的返回给客户端了