Skip to content

Commit

Permalink
聊天初代版本
Browse files Browse the repository at this point in the history
  • Loading branch information
cph999 committed Oct 14, 2024
1 parent 478a2ac commit f1935f9
Show file tree
Hide file tree
Showing 14 changed files with 354 additions and 79 deletions.
4 changes: 4 additions & 0 deletions musicBackend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
<artifactId>com.acrcloud.sdks.recognizer</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.cph.musicbackend;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
@MapperScan("com.cph.musicbackend.mapper")
public class MusicBackendApplication {

public static void main(String[] args) {
Expand Down
40 changes: 40 additions & 0 deletions musicBackend/src/main/java/com/cph/musicbackend/a.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket Chat</title>
</head>
<body>
<div>
<input type="text" id="messageInput" placeholder="Type a message..." />
<button onclick="sendMessage()">Send</button>
</div>
<div id="messages"></div>

<script>
const ws = new WebSocket('ws://localhost:8809/chat');

ws.onmessage = function(event) {
const messagesDiv = document.getElementById('messages');
const newMessage = document.createElement('div');
newMessage.textContent = event.data;
messagesDiv.appendChild(newMessage);
};

function sendMessage() {
const input = document.getElementById('messageInput');
ws.send(input.value);
input.value = '';
}

ws.onopen = function() {
console.log('Connected to WebSocket server');
};

ws.onclose = function() {
console.log('Disconnected from WebSocket server');
};
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.cph.musicbackend.config;

import com.cph.musicbackend.handler.ChatWebSocketHandler;
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;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new ChatWebSocketHandler(), "/api/chat")
.setAllowedOrigins("*"); // 允许跨域请求,可以根据需要配置
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public CommonResult getAllMessages() {
collect.values().forEach(temp -> {
if (!CollectionUtils.isEmpty(temp)) {
lists.add(temp.stream()
.sorted((a, b) -> b.getCreatedTime().compareTo(a.getCreatedTime())) // 按照创建时间排序
.sorted(Comparator.comparing(Message::getCreatedTime)) // 按照创建时间排序
.map(m -> {
String formattedDate = sdf.format(m.getCreatedTime());
m.setShowTime(formattedDate);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.cph.musicbackend.handler;

import com.cph.musicbackend.entity.Message;
import com.cph.musicbackend.mapper.MessageMapper;
import com.cph.musicbackend.utils.SpringContextUtil;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
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.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;


public class ChatWebSocketHandler extends TextWebSocketHandler {

// 存储所有活跃的WebSocket会话
private static ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
Map<String, String> params = getQueryParams(session);
String userId = params.get("userId");
if (userId != null) {
// 在session的属性中存储userId
session.getAttributes().put("userId", userId);
sessions.put(userId, session); // 将新的会话添加到map中
}
}

@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
MessageMapper messageMapper = SpringContextUtil.getBean(MessageMapper.class);
String payload = message.getPayload();
Gson gson = new Gson();
Message m = gson.fromJson(payload, Message.class);
messageMapper.insert(m);

// 将接收到的消息发送给指定用户
WebSocketSession targetSession = sessions.get(m.getToId().toString());
if (targetSession != null && targetSession.isOpen()) {
targetSession.sendMessage(new TextMessage(gson.toJson(m)));
}
}

@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// 获取存储在session中的userId
String userId = (String) session.getAttributes().get("userId");
if (userId != null) {
sessions.remove(userId); // 移除对应的会话
}
}

private Map<String, String> getQueryParams(WebSocketSession session) {
String query = session.getUri().getQuery();
return Arrays.stream(query.split("&"))
.map(param -> param.split("="))
.collect(Collectors.toMap(
keyValue -> keyValue[0],
keyValue -> keyValue[1]
));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.cph.musicbackend.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtil implements ApplicationContextAware {

private static ApplicationContext context;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}

public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}

public static Object getBean(String beanName) {
return context.getBean(beanName);
}
}
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.7",
"emoji-picker-react": "^4.12.0",
"lamejs": "^1.2.1",
"react": "^18.3.1",
"react-audio-player": "^0.17.0",
Expand Down
Loading

0 comments on commit f1935f9

Please sign in to comment.