websocket实现简易聊天室
又做了一个关于websocket广播和在线人数统计的练习,实现一个简易的聊天室。
前端vue3
前端里的内容主要包含:
1.css的animation来实现公告从右到左的轮播。
2.websocket的onmessage里对不同消息的处理。
html
<template>
<div class="common-layout">
<el-container>
<el-header>
<el-row>
<el-col :span="1"><div>公告:</div></el-col>
<el-col :span="20">
<div class="scroll-container">
<div class="text-scroll">
公告信息
</div>
</div>
</el-col>
<el-col :span="3" class="paddingleft20">
在线人数:<span class="spanTip">{{onlineCount}}</span>
</el-col>
</el-row>
</el-header>
<el-container>
<el-aside>
<el-row v-for="(item, index) in onlineUsers" :key="index">
<span class="onlinespan">{{item}}</span>
</el-row>
</el-aside>
<el-container>
<el-main v-html="othermessage">
</el-main>
<el-footer>
<el-row>
<el-col :span="22">
<el-input v-model="this.message" :rows="2" resize="none" type="textarea"
@keyup.enter="sendMessage()"/>
</el-col>
<el-col :span="2" class="center">
<el-button type="primary" @click="sendMessage()">发送</el-button>
</el-col>
</el-row>
</el-footer>
</el-container>
</el-container>
</el-container>
</div>
</template>
<script >
import { ref } from 'vue';
const socket = new WebSocket('ws://localhost:8080/chartroom');
const othermessage=ref('')
const onlineCount=ref(0)
const onlineUsers=ref([])
const own=ref('')
export default {
name: 'Chart-Room',
components: {
},
data(){
return{
message:'',
othermessage,
onlineCount,
onlineUsers,
own
}
},
mounted(){
this.connect();
},
unmounted(){
this.beforeDestroy();
},
methods:{
connect() {
socket.onopen = function() {
};
socket.onmessage = function(event) {
if(event.data.indexOf('onlineCount:')>-1){
onlineCount.value=event.data.split(':')[1]
}else if(event.data.indexOf('onlineUsers:')>-1){
var userStr=event.data.split(':')[1];
onlineUsers.value=userStr.split(',')
}else if(event.data.indexOf('own')>-1){
own.value=event.data.split(':')[1]
}else{
othermessage.value += "<div>"+event.data+"</div>"
}
};
socket.onerror = function(event) {
console.error('WebSocket error observed:', event);
};
},
beforeDestroy() {
if (socket) {
socket.close();
}
},
sendMessage() {
if (socket.readyState === WebSocket.OPEN) {
socket.send(own.value+":"+this.message);
this.message=""
}
},
}
}
</script>
<style scoped>
.el-header{
background-color:rgb(164, 172, 184);
color: rgb(252, 252, 252);
text-align: left;
padding: 10px 15px;
height:40px;
}
.el-aside{
background-color:rgb(204, 209, 214);
width:180px;
height: 300px;
}
.el-main{
background-color:rgb(246, 250, 253);
padding: 10px 10px;
white-space: pre-wrap;
font-size: 14px;
}
.el-footer{
margin:0px;
padding:3px 3px;
background-color:rgb(237, 241, 245);
}
.center{
text-align: center;
padding: 10px 5px;
}
.scroll-container {
overflow: hidden;
white-space: nowrap;
text-align: right;
}
.text-scroll {
display: inline-block;
/** 实现从右到左的动画效果 */
animation: scroll-right 30s linear infinite;
}
@keyframes scroll-right {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
.paddingleft20{
padding-left: 20px;
}
.spanTip{
color: rgb(252, 229, 179);
}
.onlinespan{
margin:10px;
color: rgb(85, 106, 128);
}
</style>
后端java+mongodb
1.config配置
java
@Configuration
@EnableWebSocket
public class ChartConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(chartHandler(), "/chartroom")
.setAllowedOrigins("*"); // 允许跨域
}
@Bean
public ChartHandler chartHandler() {
return new ChartHandler();
}
}
2.处理连接成功后增加在线人数、断开连接后减少在线人数以及广播和单独发送消息。
java
public class ChartHandler extends TextWebSocketHandler {
private static final Set<WebSocketSession> sessionsSet = Collections.synchronizedSet(new HashSet<>());
/**
* 接收消息
*/
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
//记录到mongodb
Map<String, String> map = new HashMap<>();
map.put("time", new Date().toString());
String msg=message.getPayload().trim();
map.put("message", msg.split(":")[1]);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String currentDate = sdf.format(new Date());
MongoDBUtil.insertContent(currentDate, msg.split(":")[0], map);
// 发送消息给客户端
sendMessageToAll(message.getPayload());
}
/**
* 连接后的处理
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessionsSet.add(session);
sendMessageToAll("onlineCount:" + sessionsSet.size());
sendMessageToAll("onlineUsers:" + getListUsers());
session.sendMessage(new TextMessage("own:【游客】"+session.getId().substring(0, 8)));
}
/**
* 获取在线用户列表
*/
private String getListUsers() {
List<String> usersList = new ArrayList<>();
for(WebSocketSession item : sessionsSet){
String userName="【游客】"+item.getId().substring(0, 8);
if(!usersList.contains(userName)){
usersList.add(userName);
}
}
return String.join(",", usersList);
}
/**
* 关闭连接后的处理
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
sessionsSet.remove(session);
sendMessageToAll("onlineCount:" + sessionsSet.size());
sendMessageToAll("onlineUsers:" + getListUsers());
}
/**
* 广播发送消息
*/
private void sendMessageToAll(String message) {
sessionsSet.forEach(item -> {
try {
item.sendMessage(new TextMessage(message));
} catch (IOException e) {
e.printStackTrace();
}
});
}
}