application.yml配置:
spring:
datasource:
username: root
password: root
url: jdbc:mysql://127.0.0.1:3306/chat?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.jdbc.Driver
#指定数据源
type: com.alibaba.druid.pool.DruidDataSource
# 数据源其他配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
thymeleaf:
suffix: .html
prefix:
classpath: /templates/
cache: false
jackson: #返回的日期字段的格式
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false # true 使用时间戳显示时间
http:
multipart:
max-file-size: 1000Mb
max-request-size: 1000Mb
#配置文件式开发
mybatis:
#全局配置文件的位置
config-location: classpath:mybatis/mybatis-config.xml
#所有sql映射配置文件的位置
mapper-locations: classpath:mybatis/mapper/**/*.xml
server:
session:
timeout: 7200
演示视频:
springboot+websocket聊天系统java聊天室源码
package com.chat.controller;
import com.alibaba.fastjson.JSONObject;
import com.chat.bean.ChatMsg;
import com.chat.service.ChatMsgService;
import com.chat.util.EmojiFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
@Controller
@ServerEndpoint(value = "/websocket/{userno}")
public class ChatWebSocket {
// 这里使用静态,让 service 属于类
private static ChatMsgService chatMsgService;
// 注入的时候,给类的 service 注入
@Autowired
public void setChatService(ChatMsgService chatService) {
ChatWebSocket.chatMsgService = chatService;
}
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static ConcurrentHashMap<String, ChatWebSocket> webSocketSet = new ConcurrentHashMap<String, ChatWebSocket>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session WebSocketsession;
//当前发消息的人员编号
private String userno = "";
/**
* 连接建立成功调用的方法
*
* session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(@PathParam(value = "userno") String param, Session WebSocketsession) {
userno = param;//接收到发送消息的人员编号
this.WebSocketsession = WebSocketsession;
webSocketSet.put(param, this);//加入map中
addOnlineCount(); //在线数加1
//System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
if (!userno.equals("")) {
webSocketSet.remove(userno); //从set中删除
subOnlineCount(); //在线数减1
//System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}
}
/**
* 收到客户端消息后调用的方法
*
* @param chatmsg 客户端发送过来的消息
* @param session 可选的参数
*/
@SuppressWarnings("unused")
@OnMessage
public void onMessage(String chatmsg, Session session) {
JSONObject jsonObject = JSONObject.parseObject(chatmsg);
//给指定的人发消息
sendToUser(jsonObject.toJavaObject(ChatMsg.class));
//sendAll(message);
}
/**
* 给指定的人发送消息
*
* @param chatMsg 消息对象
*/
public void sendToUser(ChatMsg chatMsg) {
String reviceUserid = chatMsg.getReciveuserid();
String sendMessage = chatMsg.getSendtext();
sendMessage= EmojiFilter.filterEmoji(sendMessage);//过滤输入法输入的表情
chatMsgService.InsertChatMsg(new ChatMsg().setMsgtype(chatMsg.getMsgtype()).setReciveuserid(reviceUserid).setSenduserid(userno).setSendtext(sendMessage));
try {
if (webSocketSet.get(reviceUserid) != null) {
webSocketSet.get(reviceUserid).sendMessage(userno+"|"+sendMessage);
}else{
webSocketSet.get(userno).sendMessage("0"+"|"+"当前用户不在线");
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 给所有人发消息
*
* @param message
*/
private void sendAll(String message) {
String sendMessage = message.split("[|]")[1];
//遍历HashMap
for (String key : webSocketSet.keySet()) {
try {
//判断接收用户是否是当前发消息的用户
if (!userno.equals(key)) {
webSocketSet.get(key).sendMessage(sendMessage);
System.out.println("key = " + key);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 发生错误时调用
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
this.WebSocketsession.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
ChatWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount() {
ChatWebSocket.onlineCount--;
}
}
package com.chat.controller;
import com.alibaba.fastjson.JSONObject;
import com.chat.bean.ChatFriends;
import com.chat.bean.ChatMsg;
import com.chat.bean.Userinfo;
import com.chat.service.ChatFriendsService;
import com.chat.service.ChatMsgService;
import com.chat.service.LoginService;
import com.chat.util.EmojiFilter;
import com.chat.util.exception.R;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
@Controller
public class ChatCtrl {
@Autowired
ChatFriendsService chatFriendsService;
@Autowired
ChatMsgService chatMsgService;
@Autowired
LoginService loginService;
/**
* 上传聊天图片
* **/
@PostMapping(value = "/chat/upimg")
@ResponseBody
public JSONObject upauz(@RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
JSONObject res = new JSONObject();
JSONObject resUrl = new JSONObject();
LocalDate today = LocalDate.now();
Instant timestamp = Instant.now();
String ext = FilenameUtils.getExtension(file.getOriginalFilename());
String filenames = today + String.valueOf(timestamp.toEpochMilli()) + "."+ext;
File file1= new File("D:\\chat\\" + filenames);
file1.getParentFile().mkdir();
file.transferTo(file1);
resUrl.put("src", "/pic/" + filenames);
res.put("msg", "");
res.put("code", 0);
res.put("data", resUrl);
return res;
}
/**
* 添加好友:查询用户
* */
@PostMapping("/chat/lkuser/{username}")
@ResponseBody public R lkuser(@PathVariable("username")String username){
username= EmojiFilter.filterEmoji(username);
String uid = loginService.lkUseridByUsername(username);
if(uid==null){
return R.error().message("未查询到此用户");
}
return R.ok().data("userinfo",chatFriendsService.LkUserinfoByUserid(uid)).message("用户信息");
}
/**
* 添加好友
* */
@PostMapping("/chat/adduser/{fuserid}")
@ResponseBody public R tofuseridchat(@PathVariable("fuserid")String fuserid,HttpSession session){
String userid=(String)session.getAttribute("userid");
if(userid.equals(fuserid)){
return R.error().message("不能添加自己为好友");
}
ChatFriends chatFriends=new ChatFriends();
chatFriends.setUserid(userid).setFuserid(fuserid);
Integer integer = chatFriendsService.JustTwoUserIsFriend(chatFriends);
if(integer==null){
//如果不存在好友关系插入好友关系
chatFriendsService.InsertUserFriend(chatFriends);
chatFriendsService.InsertUserFriend(new ChatFriends().setFuserid(userid).setUserid(fuserid));
}
return R.ok().message("添加成功");
}
/**
* 跳转到聊天
* */
@GetMapping("/chat/ct")
public String tochat(){
return "/chat/chats";
}
/***
* 查询用户的好友
* */
@PostMapping("/chat/lkfriends")
@ResponseBody public List<ChatFriends> lkfriends(HttpSession session){
String userid=(String)session.getAttribute("userid");
return chatFriendsService.LookUserAllFriends(userid);
}
/***
* 查询两个用户之间的聊天记录
* */
@PostMapping("/chat/lkuschatmsg/{reviceuserid}")
@ResponseBody public List<ChatMsg> lkfriends(HttpSession session, @PathVariable("reviceuserid")String reviceuserid){
String userid=(String)session.getAttribute("userid");
return chatMsgService.LookTwoUserMsg(new ChatMsg().setSenduserid(userid).setReciveuserid(reviceuserid));
}
/***
* Ajax上传web界面js录制的音频数据
* */
@PostMapping("/chat/audio")
@ResponseBody
public JSONObject upaudio(@RequestParam(value = "file") MultipartFile file) throws IOException {
JSONObject res = new JSONObject();
JSONObject resUrl = new JSONObject();
LocalDate today = LocalDate.now();
Instant timestamp = Instant.now();
String filenames = today + String.valueOf(timestamp.toEpochMilli()) + ".mp3";
String pathname = "D:\\chat\\" + filenames;
file.transferTo(new File(pathname));
resUrl.put("src", "/pic/"+filenames);
res.put("msg", "");
res.put("data", resUrl);
return res;
}
@GetMapping("/getUserInfo/{userid}")
@ResponseBody
public R userInfo(@PathVariable("userid") String userid) {
Userinfo userinfo = chatFriendsService.LkUserinfoByUserid(userid);
HashMap<String, Object> map = new HashMap<>();
map.put("data", userinfo);
return R.ok().data(map);
}
@PostMapping("/updateUser")
@ResponseBody
public R updateUser(HttpSession session, @RequestBody Userinfo userinfo) {
boolean result = chatFriendsService.updateUser(userinfo, session);
if (result) {
return R.ok();
}
return R.error();
}
}