弹幕发送功能‘简单’实现
导入依赖
<!-- websocket弹幕依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
后端代码
package com.by.danmaku;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
/**
* @author lenovo
* @version 0.1
* @className WebSocketConfig
* @date 2024/11/20 19:21
* @since jdk11
*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// 注册 WebSocket 处理器
registry.addHandler(new DanmakuWebSocketHandler(), "/danmaku")
.setAllowedOrigins("*"); // 允许所有来源,生产环境中应限制为特定来源
}
}
package com.by.danmaku;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* @author lenovo
* @version 0.1
* @className DanmakuWebSocketHandler
* @date 2024/11/20 19:35
* @since jdk11
*/
@Slf4j
@Component
public class DanmakuWebSocketHandler extends TextWebSocketHandler {
private static final CopyOnWriteArraySet<WebSocketSession> sessions = new CopyOnWriteArraySet<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
log.debug("欢迎进入直播间");
sessions.add(session);
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// 处理接收到的消息
String payload = message.getPayload();
log.debug("收到消息:{}",payload);
for (WebSocketSession s : sessions){
s.sendMessage(new TextMessage(payload));
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
log.debug("有人离开直播间");
sessions.remove(session);
}
}
前端代码
<template>
<div class="container">
<vue-danmaku class="danmaku" v-model:danmus="danmus" :speeds="50" :channels="2" useSlot>
<template v-slot:dm="{ danmu }">
{{ danmu }}
</template>
</vue-danmaku>
</div>
<div>
<el-input class="textarea" v-model="textarea" :rows="2" type="textarea" placeholder="请输入弹幕" />
<el-button type="primary" @click="send">发送</el-button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import vueDanmaku from 'vue3-danmaku';
import { wmsStore } from '../store/pinia';
const store = wmsStore();
const textarea = ref('');
const danmus = ref<string[]>([]);
const socket = new WebSocket('ws://localhost:8080/danmaku');
const send = () => {
socket.send(textarea.value);
};
onMounted(() => {
socket.onopen = function (event) {
console.log('连接已打开!');
};
socket.onmessage = function (event) {
const message = event.data;
danmus.value.push(message);
console.log(danmus.value);
};
socket.onclose = function (event) {
console.log('断开!');
};
});
</script>
<style>
.container {
justify-content: center;
display: flex;
align-items: center;
}
.container .danmaku {
height: 300px;
width: 600px;
background-image: url('/public/ims.png');
}
.textarea{
width:400px;
margin-top: 20px;
margin-left: 100px;
margin-right: 20px;
display: inline-block;
}
</style>