在现代 web 应用中,语音通话功能已经成为一个重要的交互方式。通过使用 WebSocket,我们可以建立实时的双向通信,适用于语音通话的实现。下面将介绍如何在 Spring Boot 与 Vue.js 中使用 WebSocket 实现语音通话功能。
一、构建后端(Spring Boot)
首先,我们需要在 Spring Boot 中设置 WebSocket。首先,添加相关依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
然后,创建 WebSocket 配置类:
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}
接下来,创建一个控制器来处理语音数据:
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
@Controller
public class VoiceController {
private final SimpMessagingTemplate messagingTemplate;
public VoiceController(SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
@MessageMapping("/voice")
public void sendVoiceMessage(String voiceData) {
messagingTemplate.convertAndSend("/topic/voice", voiceData);
}
}
二、构建前端(Vue.js)
在 Vue.js 中,我们需要使用 sockjs-client
和 stompjs
来连接 WebSocket:
npm install sockjs-client stompjs
接下来,创建一个 Vue 组件来实现语音通话功能:
<template>
<div>
<button @click="startCall">开始通话</button>
<button @click="stopCall">结束通话</button>
<audio ref="audio" controls></audio>
</div>
</template>
<script>
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
export default {
data() {
return {
stompClient: null,
audioContext: new (window.AudioContext || window.webkitAudioContext)(),
};
},
methods: {
connect() {
const socket = new SockJS('http://localhost:8080/ws');
this.stompClient = Stomp.over(socket);
this.stompClient.connect({}, frame => {
console.log('Connected: ' + frame);
this.stompClient.subscribe('/topic/voice', message => {
this.playVoice(message.body);
});
});
},
startCall() {
this.connect();
// 启动录音逻辑
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = event => {
this.sendVoice(event.data);
};
mediaRecorder.start(1000); // 每隔1秒处理一次音频数据
});
},
stopCall() {
// 停止录音逻辑
if (this.stompClient) {
this.stompClient.disconnect();
}
},
sendVoice(blob) {
const reader = new FileReader();
reader.onloadend = () => {
this.stompClient.send("/app/voice", {}, reader.result);
};
reader.readAsArrayBuffer(blob);
},
playVoice(arrayBuffer) {
this.audioContext.decodeAudioData(arrayBuffer, (buffer) => {
const source = this.audioContext.createBufferSource();
source.buffer = buffer;
source.connect(this.audioContext.destination);
source.start(0);
});
}
}
};
</script>
三、总结
通过上述代码,我们已经实现了一个简单的语音通话功能。后端使用 Spring Boot 提供 WebSocket 服务,前端使用 Vue.js 连接 WebSocket 并处理音频数据。实际应用中,我们可能还需要处理更复杂的场景,例如用户认证、音频的压缩/解压缩等。这只是一个基础示例,您可以在此基础上进行扩展和优化。