springboot+websocket聊天系统java聊天室源码

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();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿毕业分享网

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值