美文网首页
基于Springboot和WebScoket写的一个在线聊天小程

基于Springboot和WebScoket写的一个在线聊天小程

作者: 菜鸟小谢 | 来源:发表于2020-04-28 10:47 被阅读0次

    基于Springboot和WebScoket写的一个在线聊天小程序

    (好几天没有写东西了,也没有去练手了,就看了看这个。。。)

    6

    项目说明

    • 此项目为一个聊天的小demo,采用springboot+websocket+vue开发。
    • 其中有一个接口为添加好友接口,添加好友会判断是否已经是好友。
    • 聊天的时候:A给B发送消息如果B的聊天窗口不是A,则B处会提醒A发来一条消息。
    • 聊天内容的输入框采用layui的富文本编辑器,目前不支持回车发送内容。
    • 聊天可以发送图片,图片默认存储在D:/chat/目录下。
    • 点击聊天内容中的图片会弹出预览,这个预览弹出此条消息中的所有图片。
    • 在发送语音的时候,语音默认发送给当前聊天窗口的用户,所以录制语音的时候务必保证当前聊天窗口有选择的用户。
    • 知道用户的账号可以添加好友,目前是如果账号存在,可以直接添加成功

    老规矩,还是先看看小项目的目录结构:

    1

    一、先引入pom文件

    这里就只放了一点点代码(代码太长了)

    <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.4</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>net.sf.json-lib</groupId>
                <artifactId>json-lib</artifactId>
                <version>2.4</version>
                <classifier>jdk15</classifier>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
                <version>2.2.4.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.60</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    

    二、创建对应的yml配置文件

    spring:
      profiles:
        active: prod
    
    spring:
      datasource:
        username: root
        password: root
        url: jdbc:mysql://localhost:3306/chat?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=UTC
        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
    

    三、创建实体类

    这里就不再多说了,有Login,Userinfo,ChatMsg,ChatFriends

    2

    四、创建对应的mapper(即dao层)还有对应的mapper映射文件

    (这里就举出了一个,不再多说)

    public interface ChatFriendsMapper {
        //查询所有的好友
        List<ChatFriends> LookUserAllFriends(String userid);
        //插入好友
        void InsertUserFriend(ChatFriends chatFriends);
        //判断是否加好友
        Integer JustTwoUserIsFriend(ChatFriends chatFriends);
        //查询用户的信息
        Userinfo LkUserinfoByUserid(String userid);
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.chat.mapper.ChatFriendsMapper">
        <select id="LookUserAllFriends" resultType="com.chat.bean.ChatFriends" parameterType="java.lang.String">
          select userid,nickname,uimg from userinfo where userid in (select a.fuserid from chat_friends a where a.userid=#{userid})
        </select>
        <insert id="InsertUserFriend" parameterType="com.chat.bean.ChatFriends">
            insert into chat_friends (userid, fuserid) value (#{userid},#{fuserid})
        </insert>
        <select id="JustTwoUserIsFriend" parameterType="com.chat.bean.ChatFriends" resultType="java.lang.Integer">
            select id from chat_friends where userid=#{userid} and fuserid=#{fuserid}
        </select>
        <select id="LkUserinfoByUserid" parameterType="java.lang.String" resultType="com.chat.bean.Userinfo">
            select * from userinfo where userid=#{userid}
        </select>
    </mapper>
    

    五、创建对应的业务类(即service)

    (同样的业务层这里也就指出一个)

    @Service
    public class ChatFriendsService {
        @Autowired
        ChatFriendsMapper chatFriendsMapper;
        public List<ChatFriends> LookUserAllFriends(String userid){
            return chatFriendsMapper.LookUserAllFriends(userid);
        }
        public void InsertUserFriend(ChatFriends chatFriends){
            chatFriendsMapper.InsertUserFriend(chatFriends);
        }
        public Integer JustTwoUserIsFriend(ChatFriends chatFriends){
            return chatFriendsMapper.JustTwoUserIsFriend(chatFriends);
        }
        public Userinfo LkUserinfoByUserid(String userid){
            return chatFriendsMapper.LkUserinfoByUserid(userid);
        }
    }
    
    

    六、创建对应的控制器

    这里再说说项目的接口

    1. /chat/upimg
      聊天图片上传接口
    2. /chat/lkuser
      这个接口用来添加好友的时候:查询用户,如果用户存在返回用户信息,如果不存在返回不存在
    3. /chat/adduser/
      这个接口是添加好友接口,会判断添加的好友是否是自己,如果添加的好友已经存在则直接返回
    4. /chat/ct
      跳转到聊天界面
    5. /chat/lkfriends
      查询用户的好友
    6. /chat/lkuschatmsg/
      这个接口是查询两个用户之间的聊天信息的接口,传入用户的userid,查询当前登录用户和该用户的聊天记录。
    7. /chat/audio
      这个接口是Ajax上传web界面js录制的音频数据用的接口

    (同样就只写一个)

    @Controller
    public class LoginCtrl {
        @Autowired
        LoginService loginService;
        @GetMapping("/")
        public String tologin(){
            return "user/login";
        }
        /**
         * 登陆
         * */
        @PostMapping("/justlogin")
        @ResponseBody
        public R login(@RequestBody Login login, HttpSession session){
            login.setPassword(Md5Util.StringInMd5(login.getPassword()));
            String userid = loginService.justLogin(login);
            if(userid==null){
                return R.error().message("账号或者密码错误");
            }
            session.setAttribute("userid",userid);
            return R.ok().message("登录成功");
        }
    }
    
    

    七、创建对应的工具类以及自定义异常类

    1. 表情过滤工具类
    public class EmojiFilter {
        private static boolean isEmojiCharacter(char codePoint) {
            return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
                    || (codePoint == 0xD)
                    || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                    || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                    || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
        }
    
        @Test
        public void testA(){
            String s = EmojiFilter.filterEmoji("您好😄,你好啊");
            System.out.println(s);
        }
    
    
    1. Md5数据加密类
       static String[] chars = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
    
        /**
         * 将普通字符串用md5加密,并转化为16进制字符串
         * @param str
         * @return
         */
        public static String StringInMd5(String str) {
    
            // 消息签名(摘要)
            MessageDigest md5 = null;
            try {
                // 参数代表的是算法名称
                md5 = MessageDigest.getInstance("md5");
                byte[] result = md5.digest(str.getBytes());
    
                StringBuilder sb = new StringBuilder(32);
                // 将结果转为16进制字符  0~9 A~F
                for (int i = 0; i < result.length; i++) {
                    // 一个字节对应两个字符
                    byte x = result[i];
                    // 取得高位
                    int h = 0x0f & (x >>> 4);
                    // 取得低位
                    int l = 0x0f & x;
                    sb.append(chars[h]).append(chars[l]);
                }
                return sb.toString();
    
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            }
        }
    
    1. 测试数据加密类
    public class TestUtil {
        @Test
        public void testA(){
            String s = Md5Util.StringInMd5("123456");
            System.out.println(s);
        }
    }
    
    

    八、引入对应的静态资源文件(这个应该一开始就做的)

    4

    九、自定义一些配置并且注入到容器里面

    1. Druid数据源
    @Configuration
    public class DruidConfig {
        @ConfigurationProperties(prefix = "spring.datasource")
        @Bean
        public DataSource druid(){
            return new DruidDataSource();
        }
        //配置Druid的监控
        //1.配置要给管理后台的Servlet
        @Bean
        public ServletRegistrationBean servletRegistrationBean(){
            ServletRegistrationBean bean=new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
            Map<String,String> initParams=new HashMap<>();
            initParams.put("loginUsername","admin");
            initParams.put("loginPassword","admin233215");
            initParams.put("allow","");//默认允许ip访问
            initParams.put("deny","");
            bean.setInitParameters(initParams);
            return bean;
        }
        //2.配置一个监控的filter
        @Bean
        public FilterRegistrationBean webStarFilter(){
            FilterRegistrationBean bean=new FilterRegistrationBean();
            bean.setFilter(new WebStatFilter());
            Map<String,String> initParams=new HashMap<>();
            initParams.put("exclusions","*.js,*.css,/druid/*");
            bean.setInitParameters(initParams);
            bean.setUrlPatterns(Arrays.asList("/*"));
            return bean;
        }
    }
    
    1. 静态资源以及拦截器
    @Configuration
    public class MyConfig extends WebMvcConfigurerAdapter {
        //配置一个静态文件的路径 否则css和js无法使用,虽然默认的静态资源是放在static下,但是没有配置里面的文件夹
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        }
        @Bean
        public WebMvcConfigurerAdapter WebMvcConfigurerAdapter() {
            WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
                @Override
                public void addResourceHandlers(ResourceHandlerRegistry registry) {
                    //registry.addResourceHandler("/pic/**").addResourceLocations("file:D:/chat/");
                    registry.addResourceHandler("/pic/**").addResourceLocations("file:D:/idea_project/SpringBoot/Project/Complete&&Finish/chat/chatmsg/");
                    super.addResourceHandlers(registry);
                }
            };
            return adapter;
        }
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //注册TestInterceptor拦截器
            InterceptorRegistration registration = registry.addInterceptor(new AdminInterceptor());
            registration.addPathPatterns("/chat/*");
        }
    }
    
    1. WebSocketConfigScokt通信配置
    @Configuration
    @EnableWebSocket
    public class WebSocketConfig {
     
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    

    十、进行测试

    这是两个不同的用户

    7
    8
    当然了,还可以进行语音,添加好友
    今天的就写到这里吧!谢谢!
    这里要提一下我的一个学长的个人博客,当然了,还有我的,谢谢

    理木客

    我的

    天涯志

    相关文章

      网友评论

          本文标题:基于Springboot和WebScoket写的一个在线聊天小程

          本文链接:https://www.haomeiwen.com/subject/rqxvwhtx.html